pyedb 0.52.0__py3-none-any.whl → 0.54.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 (97) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_common.py +12 -15
  3. pyedb/configuration/cfg_data.py +2 -2
  4. pyedb/configuration/cfg_modeler.py +163 -234
  5. pyedb/configuration/cfg_ports_sources.py +6 -8
  6. pyedb/configuration/cfg_stackup.py +62 -249
  7. pyedb/configuration/configuration.py +272 -170
  8. pyedb/dotnet/database/cell/hierarchy/model.py +1 -1
  9. pyedb/dotnet/database/cell/layout.py +1 -1
  10. pyedb/dotnet/database/cell/layout_obj.py +3 -3
  11. pyedb/dotnet/database/cell/primitive/path.py +1 -1
  12. pyedb/dotnet/database/cell/primitive/primitive.py +8 -8
  13. pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
  14. pyedb/dotnet/database/cell/terminal/point_terminal.py +1 -1
  15. pyedb/dotnet/database/cell/terminal/terminal.py +24 -26
  16. pyedb/dotnet/database/components.py +33 -27
  17. pyedb/dotnet/database/definition/component_def.py +3 -3
  18. pyedb/dotnet/database/definition/component_model.py +1 -1
  19. pyedb/dotnet/database/definition/package_def.py +1 -1
  20. pyedb/dotnet/database/dotnet/database.py +47 -38
  21. pyedb/dotnet/database/dotnet/primitive.py +16 -16
  22. pyedb/dotnet/database/edb_data/hfss_extent_info.py +6 -6
  23. pyedb/dotnet/database/edb_data/layer_data.py +17 -15
  24. pyedb/dotnet/database/edb_data/padstacks_data.py +12 -12
  25. pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
  26. pyedb/dotnet/database/edb_data/sources.py +6 -6
  27. pyedb/dotnet/database/edb_data/variables.py +7 -3
  28. pyedb/dotnet/database/geometry/point_data.py +1 -1
  29. pyedb/dotnet/database/geometry/polygon_data.py +2 -4
  30. pyedb/dotnet/database/hfss.py +7 -7
  31. pyedb/dotnet/database/materials.py +2 -2
  32. pyedb/dotnet/database/modeler.py +8 -11
  33. pyedb/dotnet/database/nets.py +1 -1
  34. pyedb/dotnet/database/padstack.py +72 -1
  35. pyedb/dotnet/database/sim_setup_data/data/settings.py +24 -0
  36. pyedb/dotnet/database/sim_setup_data/io/siwave.py +26 -1
  37. pyedb/dotnet/database/siwave.py +19 -5
  38. pyedb/dotnet/database/stackup.py +80 -137
  39. pyedb/dotnet/database/utilities/heatsink.py +4 -4
  40. pyedb/dotnet/database/utilities/obj_base.py +1 -1
  41. pyedb/dotnet/database/utilities/simulation_setup.py +1 -1
  42. pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +894 -0
  43. pyedb/dotnet/database/utilities/siwave_simulation_setup.py +15 -0
  44. pyedb/dotnet/database/utilities/value.py +116 -0
  45. pyedb/dotnet/edb.py +58 -45
  46. pyedb/generic/design_types.py +39 -1
  47. pyedb/generic/grpc_warnings.py +5 -0
  48. pyedb/grpc/__init__.py +0 -0
  49. pyedb/grpc/database/components.py +155 -98
  50. pyedb/grpc/database/control_file.py +240 -193
  51. pyedb/grpc/database/definition/materials.py +23 -30
  52. pyedb/grpc/database/definition/package_def.py +15 -15
  53. pyedb/grpc/database/definition/padstack_def.py +51 -51
  54. pyedb/grpc/database/definitions.py +7 -5
  55. pyedb/grpc/database/geometry/arc_data.py +7 -5
  56. pyedb/grpc/database/geometry/point_3d_data.py +8 -7
  57. pyedb/grpc/database/geometry/polygon_data.py +3 -2
  58. pyedb/grpc/database/hierarchy/component.py +43 -38
  59. pyedb/grpc/database/hierarchy/pin_pair_model.py +15 -14
  60. pyedb/grpc/database/hierarchy/pingroup.py +9 -9
  61. pyedb/grpc/database/layers/stackup_layer.py +45 -44
  62. pyedb/grpc/database/layout/layout.py +9 -8
  63. pyedb/grpc/database/layout/voltage_regulator.py +7 -7
  64. pyedb/grpc/database/layout_validation.py +13 -12
  65. pyedb/grpc/database/modeler.py +156 -131
  66. pyedb/grpc/database/nets.py +42 -31
  67. pyedb/grpc/database/padstacks.py +270 -175
  68. pyedb/grpc/database/ports/ports.py +5 -6
  69. pyedb/grpc/database/primitive/bondwire.py +8 -7
  70. pyedb/grpc/database/primitive/circle.py +4 -4
  71. pyedb/grpc/database/primitive/padstack_instance.py +18 -18
  72. pyedb/grpc/database/primitive/path.py +7 -7
  73. pyedb/grpc/database/primitive/polygon.py +3 -3
  74. pyedb/grpc/database/primitive/primitive.py +13 -17
  75. pyedb/grpc/database/primitive/rectangle.py +13 -13
  76. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +1 -1
  77. pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +10 -0
  78. pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +961 -0
  79. pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +17 -1
  80. pyedb/grpc/database/siwave.py +44 -24
  81. pyedb/grpc/database/source_excitations.py +333 -229
  82. pyedb/grpc/database/stackup.py +164 -147
  83. pyedb/grpc/database/terminal/bundle_terminal.py +17 -7
  84. pyedb/grpc/database/terminal/edge_terminal.py +10 -0
  85. pyedb/grpc/database/terminal/padstack_instance_terminal.py +15 -4
  86. pyedb/grpc/database/terminal/pingroup_terminal.py +11 -10
  87. pyedb/grpc/database/terminal/point_terminal.py +4 -3
  88. pyedb/grpc/database/terminal/terminal.py +9 -9
  89. pyedb/grpc/database/utility/value.py +109 -0
  90. pyedb/grpc/edb.py +129 -45
  91. pyedb/grpc/edb_init.py +0 -7
  92. pyedb/siwave_core/cpa/simulation_setup_data_model.py +132 -0
  93. pyedb/siwave_core/product_properties.py +198 -0
  94. {pyedb-0.52.0.dist-info → pyedb-0.54.0.dist-info}/METADATA +15 -13
  95. {pyedb-0.52.0.dist-info → pyedb-0.54.0.dist-info}/RECORD +97 -89
  96. {pyedb-0.52.0.dist-info → pyedb-0.54.0.dist-info}/WHEEL +1 -1
  97. {pyedb-0.52.0.dist-info → pyedb-0.54.0.dist-info/licenses}/LICENSE +0 -0
@@ -31,6 +31,7 @@ from collections import OrderedDict
31
31
  import json
32
32
  import logging
33
33
  import math
34
+ from typing import Any, Dict, List, Optional, Tuple, Union
34
35
  import warnings
35
36
 
36
37
  from ansys.edb.core.definition.die_property import DieOrientation as GrpcDieOrientation
@@ -49,11 +50,11 @@ from ansys.edb.core.layer.layer_collection import LayerCollection as GrpcLayerCo
49
50
  from ansys.edb.core.layer.layer_collection import LayerTypeSet as GrpcLayerTypeSet
50
51
  from ansys.edb.core.layer.stackup_layer import StackupLayer as GrpcStackupLayer
51
52
  from ansys.edb.core.layout.mcad_model import McadModel as GrpcMcadModel
52
- from ansys.edb.core.utility.value import Value as GrpcValue
53
53
 
54
54
  from pyedb.generic.general_methods import ET, generate_unique_name
55
55
  from pyedb.grpc.database.layers.layer import Layer
56
56
  from pyedb.grpc.database.layers.stackup_layer import StackupLayer
57
+ from pyedb.grpc.database.utility.value import Value
57
58
  from pyedb.misc.aedtlib_personalib_install import write_pretty_xml
58
59
 
59
60
  colors = None
@@ -104,7 +105,7 @@ class LayerCollection(GrpcLayerCollection):
104
105
  """
105
106
  self._pedb.layout.layer_collection = self
106
107
 
107
- def add_layer_top(self, name, layer_type="signal", **kwargs):
108
+ def add_layer_top(self, name: str, layer_type: str = "signal", **kwargs) -> Union["Layer", None]:
108
109
  """Add a layer on top of the stackup.
109
110
 
110
111
  Parameters
@@ -130,10 +131,10 @@ class LayerCollection(GrpcLayerCollection):
130
131
  >>> top_layer = edb.stackup.add_layer_top("NewTopLayer", layer_type="signal", thickness="0.1mm",
131
132
  ... material="copper")
132
133
  """
133
- thickness = GrpcValue(0.0)
134
+ thickness = Value(0.0)
134
135
  if "thickness" in kwargs:
135
- thickness = GrpcValue(kwargs["thickness"])
136
- elevation = GrpcValue(0.0)
136
+ thickness = Value(kwargs["thickness"])
137
+ elevation = Value(0.0)
137
138
  _layer_type = GrpcLayerType.SIGNAL_LAYER
138
139
  if layer_type.lower() == "dielectric":
139
140
  _layer_type = GrpcLayerType.DIELECTRIC_LAYER
@@ -142,7 +143,7 @@ class LayerCollection(GrpcLayerCollection):
142
143
  )
143
144
  return self._layer_collection.add_layer_top(layer)
144
145
 
145
- def add_layer_bottom(self, name, layer_type="signal", **kwargs):
146
+ def add_layer_bottom(self, name: str, layer_type: str = "signal", **kwargs) -> Union["Layer", None]:
146
147
  """Add a layer at the bottom of the stackup.
147
148
 
148
149
  Parameters
@@ -169,11 +170,11 @@ class LayerCollection(GrpcLayerCollection):
169
170
  >>> bot_layer = edb.stackup.add_layer_bottom("NewBottomLayer", layer_type="signal", thickness="0.1mm",
170
171
  ... material="copper")
171
172
  """
172
- thickness = GrpcValue(0.0)
173
+ thickness = Value(0.0)
173
174
  layer_type_map = {"dielectric": GrpcLayerType.DIELECTRIC_LAYER, "signal": GrpcLayerType.SIGNAL_LAYER}
174
175
  if "thickness" in kwargs:
175
- thickness = GrpcValue(kwargs["thickness"])
176
- elevation = GrpcValue(0.0)
176
+ thickness = Value(kwargs["thickness"])
177
+ elevation = Value(0.0)
177
178
  if "type" in kwargs:
178
179
  _layer_type = layer_type_map[kwargs["type"]]
179
180
  else:
@@ -189,7 +190,9 @@ class LayerCollection(GrpcLayerCollection):
189
190
  layer.set_fill_material(kwargs["fill_material"])
190
191
  return self._layer_collection.add_layer_bottom(layer)
191
192
 
192
- def add_layer_below(self, name, base_layer_name, layer_type="signal", **kwargs):
193
+ def add_layer_below(
194
+ self, name: str, base_layer_name: str, layer_type: str = "signal", **kwargs
195
+ ) -> Union["Layer", None]:
193
196
  """Add a layer below a specified layer.
194
197
 
195
198
  Parameters
@@ -216,10 +219,10 @@ class LayerCollection(GrpcLayerCollection):
216
219
  >>> edb = Edb()
217
220
  >>> new_layer = edb.stackup.add_layer_below("NewLayer", "TopLayer", layer_type="dielectric", thickness="0.05mm")
218
221
  """
219
- thickness = GrpcValue(0.0)
222
+ thickness = Value(0.0)
220
223
  if "thickness" in kwargs:
221
- thickness = GrpcValue(kwargs["thickness"])
222
- elevation = GrpcValue(0.0)
224
+ thickness = Value(kwargs["thickness"])
225
+ elevation = Value(0.0)
223
226
  if "type" in kwargs:
224
227
  _l_map = {"signal": GrpcLayerType.SIGNAL_LAYER, "dielectric": GrpcLayerType.DIELECTRIC_LAYER}
225
228
  _layer_type = _l_map[kwargs["type"]]
@@ -236,7 +239,9 @@ class LayerCollection(GrpcLayerCollection):
236
239
  )
237
240
  return self._layer_collection.add_layer_below(layer, base_layer_name)
238
241
 
239
- def add_layer_above(self, name, base_layer_name, layer_type="signal", **kwargs):
242
+ def add_layer_above(
243
+ self, name: str, base_layer_name: str, layer_type: str = "signal", **kwargs
244
+ ) -> Union["Layer", None]:
240
245
  """Add a layer above a specified layer.
241
246
 
242
247
  Parameters
@@ -263,10 +268,10 @@ class LayerCollection(GrpcLayerCollection):
263
268
  >>> edb = Edb()
264
269
  >>> new_layer = edb.stackup.add_layer_above("NewLayer", "BottomLayer", layer_type="signal", thickness="0.05mm")
265
270
  """
266
- thickness = GrpcValue(0.0)
271
+ thickness = Value(0.0)
267
272
  if "thickness" in kwargs:
268
- thickness = GrpcValue(kwargs["thickness"])
269
- elevation = GrpcValue(0.0)
273
+ thickness = Value(kwargs["thickness"])
274
+ elevation = Value(0.0)
270
275
  _layer_type = GrpcLayerType.SIGNAL_LAYER
271
276
  if layer_type.lower() == "dielectric":
272
277
  _layer_type = GrpcLayerType.DIELECTRIC_LAYER
@@ -275,7 +280,7 @@ class LayerCollection(GrpcLayerCollection):
275
280
  )
276
281
  return self._layer_collection.add_layer_above(layer, base_layer_name)
277
282
 
278
- def add_document_layer(self, name, layer_type="user", **kwargs):
283
+ def add_document_layer(self, name: str, layer_type: str = "user", **kwargs: Any) -> Optional["Layer"]:
279
284
  """Add a document layer.
280
285
 
281
286
  Parameters
@@ -318,7 +323,7 @@ class LayerCollection(GrpcLayerCollection):
318
323
  return self.layers
319
324
 
320
325
  @property
321
- def non_stackup_layers(self):
326
+ def non_stackup_layers(self) -> Dict[str, Layer]:
322
327
  """Retrieve the dictionary of non-stackup layers.
323
328
 
324
329
  Returns
@@ -337,7 +342,7 @@ class LayerCollection(GrpcLayerCollection):
337
342
  }
338
343
 
339
344
  @property
340
- def all_layers(self):
345
+ def all_layers(self) -> Dict[str, Layer]:
341
346
  """Retrieve all layers.
342
347
 
343
348
  Returns
@@ -354,7 +359,7 @@ class LayerCollection(GrpcLayerCollection):
354
359
  return {layer.name: Layer(self._pedb, layer) for layer in self.get_layers(GrpcLayerTypeSet.ALL_LAYER_SET)}
355
360
 
356
361
  @property
357
- def signal_layers(self):
362
+ def signal_layers(self) -> Dict[str, StackupLayer]:
358
363
  """Retrieve the dictionary of signal layers.
359
364
 
360
365
  Returns
@@ -373,7 +378,7 @@ class LayerCollection(GrpcLayerCollection):
373
378
  }
374
379
 
375
380
  @property
376
- def dielectric_layers(self):
381
+ def dielectric_layers(self) -> Dict[str, StackupLayer]:
377
382
  """Retrieve the dictionary of dielectric layers.
378
383
 
379
384
  Returns
@@ -393,7 +398,7 @@ class LayerCollection(GrpcLayerCollection):
393
398
  }
394
399
 
395
400
  @property
396
- def layers_by_id(self):
401
+ def layers_by_id(self) -> List[List[Union[int, str]]]:
397
402
  """Retrieve the list of layers with their IDs.
398
403
 
399
404
  Returns
@@ -410,7 +415,7 @@ class LayerCollection(GrpcLayerCollection):
410
415
  return [[obj.id, name] for name, obj in self.all_layers.items()]
411
416
 
412
417
  @property
413
- def layers(self):
418
+ def layers(self) -> Dict[str, StackupLayer]:
414
419
  """Retrieve the dictionary of stackup layers (signal and dielectric).
415
420
 
416
421
  Returns
@@ -486,7 +491,7 @@ class Stackup(LayerCollection):
486
491
  return self._pedb.logger
487
492
 
488
493
  @property
489
- def thickness(self):
494
+ def thickness(self) -> float:
490
495
  """Retrieve the stackup thickness.
491
496
 
492
497
  Returns
@@ -503,7 +508,7 @@ class Stackup(LayerCollection):
503
508
  return self.get_layout_thickness()
504
509
 
505
510
  @property
506
- def num_layers(self):
511
+ def num_layers(self) -> int:
507
512
  """Retrieve the number of layers in the stackup.
508
513
 
509
514
  Returns
@@ -521,14 +526,14 @@ class Stackup(LayerCollection):
521
526
 
522
527
  def create_symmetric_stackup(
523
528
  self,
524
- layer_count,
525
- inner_layer_thickness="17um",
526
- outer_layer_thickness="50um",
527
- dielectric_thickness="100um",
528
- dielectric_material="FR4_epoxy",
529
- soldermask=True,
530
- soldermask_thickness="20um",
531
- ) -> bool: # pragma: no cover
529
+ layer_count: int,
530
+ inner_layer_thickness: str = "17um",
531
+ outer_layer_thickness: str = "50um",
532
+ dielectric_thickness: str = "100um",
533
+ dielectric_material: str = "FR4_epoxy",
534
+ soldermask: bool = True,
535
+ soldermask_thickness: str = "20um",
536
+ ) -> bool:
532
537
  """Create a symmetric stackup.
533
538
 
534
539
  Parameters
@@ -649,7 +654,7 @@ class Stackup(LayerCollection):
649
654
  return True
650
655
 
651
656
  @property
652
- def mode(self):
657
+ def mode(self) -> str:
653
658
  """Stackup mode.
654
659
 
655
660
  Returns
@@ -683,7 +688,9 @@ class Stackup(LayerCollection):
683
688
  super(LayerCollection, self.__class__).mode.__set__(self, GrpcLayerCollectionMode.MULTIZONE)
684
689
  self.update_layout()
685
690
 
686
- def _set_layout_stackup(self, layer_clone, operation, base_layer=None, method=1):
691
+ def _set_layout_stackup(
692
+ self, layer_clone: GrpcStackupLayer, operation: str, base_layer: Optional[str] = None, method: int = 1
693
+ ) -> None:
687
694
  """Internal method. Apply stackup change into EDB.
688
695
 
689
696
  Parameters
@@ -738,23 +745,25 @@ class Stackup(LayerCollection):
738
745
  self._pedb.layout.layer_collection = lc
739
746
  return True
740
747
 
741
- def _create_stackup_layer(self, layer_name, thickness, layer_type="signal", material="copper"):
748
+ def _create_stackup_layer(
749
+ self, layer_name: str, thickness: Union[str, float], layer_type: str = "signal", material: str = "copper"
750
+ ) -> StackupLayer:
742
751
  if layer_type == "signal":
743
752
  _layer_type = GrpcLayerType.SIGNAL_LAYER
744
753
  else:
745
754
  _layer_type = GrpcLayerType.DIELECTRIC_LAYER
746
755
  material = "FR4_epoxy"
747
- thickness = GrpcValue(thickness, self._pedb.active_db)
756
+ thickness = Value(thickness, self._pedb.active_db)
748
757
  layer = StackupLayer.create(
749
758
  name=layer_name,
750
759
  layer_type=_layer_type,
751
760
  thickness=thickness,
752
- elevation=GrpcValue(0),
761
+ elevation=Value(0),
753
762
  material=material,
754
763
  )
755
764
  return layer
756
765
 
757
- def _create_nonstackup_layer(self, layer_name, layer_type):
766
+ def _create_nonstackup_layer(self, layer_name: str, layer_type: str):
758
767
  if layer_type == "conducting": # pragma: no cover
759
768
  _layer_type = GrpcLayerType.CONDUCTING_LAYER
760
769
  elif layer_type == "airlines": # pragma: no cover
@@ -791,7 +800,7 @@ class Stackup(LayerCollection):
791
800
  result = Layer.create(layer_name, _layer_type)
792
801
  return result
793
802
 
794
- def add_outline_layer(self, outline_name="Outline"):
803
+ def add_outline_layer(self, name: str = "Outline") -> bool:
795
804
  """Add an outline layer named "Outline" if it is not present.
796
805
 
797
806
  Returns
@@ -809,18 +818,18 @@ class Stackup(LayerCollection):
809
818
 
810
819
  def add_layer(
811
820
  self,
812
- layer_name,
813
- base_layer=None,
814
- method="add_on_top",
815
- layer_type="signal",
816
- material="copper",
817
- fillMaterial="FR4_epoxy",
818
- thickness="35um",
819
- etch_factor=None,
820
- is_negative=False,
821
- enable_roughness=False,
822
- elevation=None,
823
- ):
821
+ layer_name: str,
822
+ base_layer: Optional[str] = None,
823
+ method: str = "add_on_top",
824
+ layer_type: str = "signal",
825
+ material: str = "copper",
826
+ fillMaterial: str = "FR4_epoxy",
827
+ thickness: Union[str, float] = "35um",
828
+ etch_factor: Optional[float] = None,
829
+ is_negative: bool = False,
830
+ enable_roughness: bool = False,
831
+ elevation: Optional[float] = None,
832
+ ) -> bool:
824
833
  """Insert a layer into stackup.
825
834
 
826
835
  Parameters
@@ -906,7 +915,7 @@ class Stackup(LayerCollection):
906
915
  new_layer.negative = is_negative
907
916
  l1 = len(self.layers)
908
917
  if method == "add_at_elevation" and elevation:
909
- new_layer.lower_elevation = GrpcValue(elevation)
918
+ new_layer.lower_elevation = Value(elevation)
910
919
  if etch_factor:
911
920
  new_layer.etch_factor = etch_factor
912
921
  if enable_roughness:
@@ -920,7 +929,7 @@ class Stackup(LayerCollection):
920
929
  return self.non_stackup_layers[layer_name]
921
930
  return self.layers[layer_name]
922
931
 
923
- def remove_layer(self, name):
932
+ def remove_layer(self, name: str) -> bool:
924
933
  """Remove a layer from stackup.
925
934
 
926
935
  Parameters
@@ -941,7 +950,7 @@ class Stackup(LayerCollection):
941
950
  self._pedb.layout.layer_collection = new_layer_collection
942
951
  return True
943
952
 
944
- def export(self, fpath, file_format="xml", include_material_with_layer=False):
953
+ def export(self, fpath: str, file_format: str = "xml", include_material_with_layer: bool = False) -> bool:
945
954
  """Export stackup definition to a file.
946
955
 
947
956
  Parameters
@@ -1013,7 +1022,7 @@ class Stackup(LayerCollection):
1013
1022
  self._logger.warning("Method export_stackup is deprecated. Use .export.")
1014
1023
  return self.export(fpath, file_format=file_format, include_material_with_layer=include_material_with_layer)
1015
1024
 
1016
- def _export_layer_stackup_to_csv_xlsx(self, fpath=None, file_format=None):
1025
+ def _export_layer_stackup_to_csv_xlsx(self, fpath: Optional[str] = None, file_format: Optional[str] = None) -> bool:
1017
1026
  if not pd:
1018
1027
  self._pedb.logger.error("Pandas is needed. Please, install it first.")
1019
1028
  return False
@@ -1042,7 +1051,9 @@ class Stackup(LayerCollection):
1042
1051
  df.to_excel(fpath)
1043
1052
  return True
1044
1053
 
1045
- def _export_layer_stackup_to_json(self, output_file=None, include_material_with_layer=False):
1054
+ def _export_layer_stackup_to_json(
1055
+ self, output_file: Optional[str] = None, include_material_with_layer: bool = False
1056
+ ) -> bool:
1046
1057
  if not include_material_with_layer:
1047
1058
  material_out = {}
1048
1059
  for material_name, material in self._pedb.materials.materials.items():
@@ -1073,7 +1084,7 @@ class Stackup(LayerCollection):
1073
1084
  else:
1074
1085
  return False
1075
1086
 
1076
- def limits(self, only_metals=False):
1087
+ def limits(self, only_metals: bool = False) -> Tuple[str, str]:
1077
1088
  """Retrieve stackup limits.
1078
1089
 
1079
1090
  Parameters
@@ -1102,7 +1113,7 @@ class Stackup(LayerCollection):
1102
1113
  lower_layer_lower_elevation = res[3]
1103
1114
  return upper_layer.name, upper_layer_top_elevationm, lower_layer.name, lower_layer_lower_elevation
1104
1115
 
1105
- def flip_design(self):
1116
+ def flip_design(self) -> bool:
1106
1117
  """Flip the current design of a layout.
1107
1118
 
1108
1119
  Returns
@@ -1124,8 +1135,8 @@ class Stackup(LayerCollection):
1124
1135
  max_elevation = 0.0
1125
1136
  for layer in lc.get_layers(GrpcLayerTypeSet.STACKUP_LAYER_SET):
1126
1137
  if "RadBox" not in layer.name: # Ignore RadBox
1127
- lower_elevation = layer.clone().lower_elevation.value * 1.0e6
1128
- upper_elevation = layer.Clone().upper_elevation.value * 1.0e6
1138
+ lower_elevation = Value(layer.clone().lower_elevation) * 1.0e6
1139
+ upper_elevation = Value(layer.Clone().upper_elevation) * 1.0e6
1129
1140
  max_elevation = max([max_elevation, lower_elevation, upper_elevation])
1130
1141
 
1131
1142
  non_stackup_layers = []
@@ -1135,9 +1146,9 @@ class Stackup(LayerCollection):
1135
1146
  non_stackup_layers.append(cloned_layer)
1136
1147
  continue
1137
1148
  if "RadBox" not in cloned_layer.name and not cloned_layer.is_via_layer:
1138
- upper_elevation = cloned_layer.upper_elevation.value * 1.0e6
1149
+ upper_elevation = Value(cloned_layer.upper_elevation) * 1.0e6
1139
1150
  updated_lower_el = max_elevation - upper_elevation
1140
- val = GrpcValue(f"{updated_lower_el}um")
1151
+ val = Value(f"{updated_lower_el}um")
1141
1152
  cloned_layer.lower_elevation = val
1142
1153
  if cloned_layer.top_bottom_association == GrpcTopBottomAssociation.TOP_ASSOCIATED:
1143
1154
  cloned_layer.top_bottom_association = GrpcTopBottomAssociation.BOTTOM_ASSOCIATED
@@ -1202,7 +1213,7 @@ class Stackup(LayerCollection):
1202
1213
  except:
1203
1214
  return False
1204
1215
 
1205
- def get_layout_thickness(self):
1216
+ def get_layout_thickness(self) -> float:
1206
1217
  """Return the layout thickness.
1207
1218
 
1208
1219
  Returns
@@ -1219,7 +1230,7 @@ class Stackup(LayerCollection):
1219
1230
  thickness = abs(top_layer.upper_elevation - bottom_layer.lower_elevation)
1220
1231
  return round(thickness, 7)
1221
1232
 
1222
- def _get_solder_height(self, layer_name):
1233
+ def _get_solder_height(self, layer_name) -> float:
1223
1234
  height = 0.0
1224
1235
  for _, val in self._pedb.components.instances.items():
1225
1236
  try:
@@ -1235,11 +1246,11 @@ class Stackup(LayerCollection):
1235
1246
  comp_prop = val.component_property
1236
1247
  port_property = comp_prop.port_property
1237
1248
  port_property.reference_size_auto = False
1238
- port_property.reference_size = (GrpcValue(0.0), GrpcValue(0.0))
1249
+ port_property.reference_size = (Value(0.0), Value(0.0))
1239
1250
  comp_prop.port_property = port_property
1240
1251
  val.component_property = comp_prop
1241
1252
 
1242
- def adjust_solder_dielectrics(self):
1253
+ def adjust_solder_dielectrics(self) -> bool:
1243
1254
  """Adjust the stack-up by adding or modifying dielectric layers that contain solder balls.
1244
1255
 
1245
1256
  This method identifies the solder-ball height and adjusts the dielectric thickness on top (or bottom)
@@ -1279,13 +1290,13 @@ class Stackup(LayerCollection):
1279
1290
 
1280
1291
  def place_in_layout(
1281
1292
  self,
1282
- edb,
1283
- angle=0.0,
1284
- offset_x=0.0,
1285
- offset_y=0.0,
1286
- flipped_stackup=True,
1287
- place_on_top=True,
1288
- ):
1293
+ edb: "Edb",
1294
+ angle: float = 0.0,
1295
+ offset_x: float = 0.0,
1296
+ offset_y: float = 0.0,
1297
+ flipped_stackup: bool = True,
1298
+ place_on_top: bool = True,
1299
+ ) -> bool:
1289
1300
  """Place current cell into another cell using layer placement method.
1290
1301
 
1291
1302
  Flip the current layer stackup of a layout if requested.
@@ -1339,9 +1350,9 @@ class Stackup(LayerCollection):
1339
1350
  elif flipped_stackup:
1340
1351
  self.flip_design()
1341
1352
  edb_cell = edb.active_cell
1342
- _angle = GrpcValue(angle * math.pi / 180.0)
1343
- _offset_x = GrpcValue(offset_x)
1344
- _offset_y = GrpcValue(offset_y)
1353
+ _angle = Value(angle * math.pi / 180.0)
1354
+ _offset_x = Value(offset_x)
1355
+ _offset_y = Value(offset_y)
1345
1356
 
1346
1357
  if edb_cell.name not in self._pedb.cell_names:
1347
1358
  list_cells = self._pedb.copy_cells([edb_cell.api_object])
@@ -1367,14 +1378,14 @@ class Stackup(LayerCollection):
1367
1378
 
1368
1379
  def place_in_layout_3d_placement(
1369
1380
  self,
1370
- edb,
1371
- angle=0.0,
1372
- offset_x=0.0,
1373
- offset_y=0.0,
1374
- flipped_stackup=True,
1375
- place_on_top=True,
1376
- solder_height=0,
1377
- ):
1381
+ edb: "Edb",
1382
+ angle: float = 0.0,
1383
+ offset_x: float = 0.0,
1384
+ offset_y: float = 0.0,
1385
+ flipped_stackup: bool = True,
1386
+ place_on_top: bool = True,
1387
+ solder_height: float = 0,
1388
+ ) -> bool:
1378
1389
  """Place current cell into another cell using 3D placement method.
1379
1390
 
1380
1391
  Flip the current layer stackup of a layout if requested.
@@ -1437,13 +1448,13 @@ class Stackup(LayerCollection):
1437
1448
  solder_height = max(lay_solder_height, solder_height)
1438
1449
  self._remove_solder_pec(lay.name)
1439
1450
 
1440
- rotation = GrpcValue(0.0)
1451
+ rotation = Value(0.0)
1441
1452
  if flipped_stackup:
1442
- rotation = GrpcValue(math.pi)
1453
+ rotation = Value(math.pi)
1443
1454
 
1444
1455
  edb_cell = edb.active_cell
1445
- _offset_x = GrpcValue(offset_x)
1446
- _offset_y = GrpcValue(offset_y)
1456
+ _offset_x = Value(offset_x)
1457
+ _offset_y = Value(offset_y)
1447
1458
 
1448
1459
  if edb_cell.name not in self._pedb.cell_names:
1449
1460
  list_cells = self._pedb.copy_cells(edb_cell)
@@ -1479,10 +1490,10 @@ class Stackup(LayerCollection):
1479
1490
  elevation = target_bottom_elevation - source_stack_top_elevation
1480
1491
  solder_height = -solder_height
1481
1492
 
1482
- h_stackup = GrpcValue(elevation + solder_height)
1493
+ h_stackup = Value(elevation + solder_height)
1483
1494
 
1484
- zero_data = GrpcValue(0.0)
1485
- one_data = GrpcValue(1.0)
1495
+ zero_data = Value(0.0)
1496
+ one_data = Value(1.0)
1486
1497
  point3d_t = GrpcPoint3DData(_offset_x, _offset_y, h_stackup)
1487
1498
  point_loc = GrpcPoint3DData(zero_data, zero_data, zero_data)
1488
1499
  point_from = GrpcPoint3DData(one_data, zero_data, zero_data)
@@ -1498,15 +1509,15 @@ class Stackup(LayerCollection):
1498
1509
 
1499
1510
  def place_instance(
1500
1511
  self,
1501
- component_edb,
1502
- angle=0.0,
1503
- offset_x=0.0,
1504
- offset_y=0.0,
1505
- offset_z=0.0,
1506
- flipped_stackup=True,
1507
- place_on_top=True,
1508
- solder_height=0,
1509
- ):
1512
+ component_edb: "Edb",
1513
+ angle: float = 0.0,
1514
+ offset_x: float = 0.0,
1515
+ offset_y: float = 0.0,
1516
+ offset_z: float = 0.0,
1517
+ flipped_stackup: bool = True,
1518
+ place_on_top: bool = True,
1519
+ solder_height: float = 0,
1520
+ ) -> GrpcCellInstance:
1510
1521
  """Place a component instance in the layout using 3D placement.
1511
1522
 
1512
1523
  Parameters
@@ -1563,8 +1574,8 @@ class Stackup(LayerCollection):
1563
1574
  solder_height = max(lay_solder_height, solder_height)
1564
1575
  component_edb.stackup._remove_solder_pec(lay.name)
1565
1576
  edb_cell = component_edb.active_cell
1566
- _offset_x = GrpcValue(offset_x)
1567
- _offset_y = GrpcValue(offset_y)
1577
+ _offset_x = Value(offset_x)
1578
+ _offset_y = Value(offset_y)
1568
1579
 
1569
1580
  if edb_cell.name not in self._pedb.cell_names:
1570
1581
  list_cells = self._pedb.copy_cells(edb_cell)
@@ -1574,12 +1585,12 @@ class Stackup(LayerCollection):
1574
1585
  edb_cell = cell
1575
1586
  # Keep Cell Independent
1576
1587
  edb_cell.is_black_box = True
1577
- rotation = GrpcValue(0.0)
1588
+ rotation = Value(0.0)
1578
1589
  if flipped_stackup:
1579
- rotation = GrpcValue(math.pi)
1590
+ rotation = Value(math.pi)
1580
1591
 
1581
- _offset_x = GrpcValue(offset_x)
1582
- _offset_y = GrpcValue(offset_y)
1592
+ _offset_x = Value(offset_x)
1593
+ _offset_y = Value(offset_y)
1583
1594
 
1584
1595
  instance_name = generate_unique_name(edb_cell.name, n=2)
1585
1596
 
@@ -1613,8 +1624,8 @@ class Stackup(LayerCollection):
1613
1624
 
1614
1625
  h_stackup = elevation + solder_height
1615
1626
 
1616
- zero_data = GrpcValue(0.0)
1617
- one_data = GrpcValue(1.0)
1627
+ zero_data = Value(0.0)
1628
+ one_data = Value(1.0)
1618
1629
  point3d_t = GrpcPoint3DData(_offset_x, _offset_y, h_stackup)
1619
1630
  point_loc = GrpcPoint3DData(zero_data, zero_data, zero_data)
1620
1631
  point_from = GrpcPoint3DData(one_data, zero_data, zero_data)
@@ -1630,12 +1641,12 @@ class Stackup(LayerCollection):
1630
1641
 
1631
1642
  def place_a3dcomp_3d_placement(
1632
1643
  self,
1633
- a3dcomp_path,
1634
- angle=0.0,
1635
- offset_x=0.0,
1636
- offset_y=0.0,
1637
- offset_z=0.0,
1638
- place_on_top=True,
1644
+ a3dcomp_path: str,
1645
+ angle: float = 0.0,
1646
+ offset_x: float = 0.0,
1647
+ offset_y: float = 0.0,
1648
+ offset_z: float = 0.0,
1649
+ place_on_top: bool = True,
1639
1650
  ) -> bool:
1640
1651
  """Place a 3D component into the current layout.
1641
1652
 
@@ -1679,13 +1690,13 @@ class Stackup(LayerCollection):
1679
1690
  res = stackup_target.get_top_bottom_stackup_layers(GrpcLayerTypeSet.SIGNAL_LAYER_SET)
1680
1691
  target_top_elevation = res[1]
1681
1692
  target_bottom_elevation = res[3]
1682
- flip_angle = GrpcValue("0deg")
1693
+ flip_angle = Value("0deg")
1683
1694
  if place_on_top:
1684
1695
  elevation = target_top_elevation + offset_z
1685
1696
  else:
1686
- flip_angle = GrpcValue("180deg")
1697
+ flip_angle = Value("180deg")
1687
1698
  elevation = target_bottom_elevation - offset_z
1688
- h_stackup = GrpcValue(elevation)
1699
+ h_stackup = Value(elevation)
1689
1700
  location = GrpcPoint3DData(offset_x, offset_y, h_stackup)
1690
1701
  mcad_model = GrpcMcadModel.create_3d_comp(layout=self._pedb.active_layout, filename=a3dcomp_path)
1691
1702
  if mcad_model.is_null: # pragma: no cover
@@ -1698,14 +1709,14 @@ class Stackup(LayerCollection):
1698
1709
 
1699
1710
  mcad_model.cell_instance.placement_3d = True
1700
1711
  transform_rotation = mcad_model.cell_instance.transform3d.create_from_axis_and_angle(
1701
- axis=rotation_axis_from, angle=flip_angle.value
1712
+ axis=rotation_axis_from, angle=Value(flip_angle)
1702
1713
  )
1703
1714
  mcad_model.cell_instance.transform3d = transform_rotation
1704
1715
  transform_translation = mcad_model.cell_instance.transform3d.create_from_offset(offset=location)
1705
1716
  mcad_model.cell_instance.transform3d = transform_translation
1706
1717
  return True
1707
1718
 
1708
- def residual_copper_area_per_layer(self):
1719
+ def residual_copper_area_per_layer(self) -> Dict[str, float]:
1709
1720
  """Report residual copper area per layer in percentage.
1710
1721
 
1711
1722
  Returns
@@ -1734,7 +1745,7 @@ class Stackup(LayerCollection):
1734
1745
  temp_data = {name: area / outline_area * 100 for name, area in temp_data.items()}
1735
1746
  return temp_data
1736
1747
 
1737
- def _import_dict(self, json_dict, rename=False):
1748
+ def _import_dict(self, json_dict: Dict[str, Any], rename: bool = False) -> bool:
1738
1749
  """Import stackup from a dictionary.
1739
1750
 
1740
1751
  Parameters
@@ -1888,7 +1899,7 @@ class Stackup(LayerCollection):
1888
1899
 
1889
1900
  return True
1890
1901
 
1891
- def _import_json(self, file_path, rename=False):
1902
+ def _import_json(self, file_path: str, rename: bool = False) -> bool:
1892
1903
  """Import stackup from a JSON file.
1893
1904
 
1894
1905
  Parameters
@@ -1908,7 +1919,7 @@ class Stackup(LayerCollection):
1908
1919
  json_dict = json.load(f) # pragma: no cover
1909
1920
  return self._import_dict(json_dict, rename)
1910
1921
 
1911
- def _import_csv(self, file_path):
1922
+ def _import_csv(self, file_path: str) -> bool:
1912
1923
  """Import stackup definition from a CSV file.
1913
1924
 
1914
1925
  Parameters
@@ -1956,7 +1967,13 @@ class Stackup(LayerCollection):
1956
1967
  self._pedb.layout.layer_collection = lc_new
1957
1968
  return True
1958
1969
 
1959
- def _set(self, layers=None, materials=None, roughness=None, non_stackup_layers=None):
1970
+ def _set(
1971
+ self,
1972
+ layers: Optional[Dict] = None,
1973
+ materials: Optional[Dict] = None,
1974
+ roughness: Optional[Dict] = None,
1975
+ non_stackup_layers: Optional[Dict] = None,
1976
+ ) -> bool:
1960
1977
  """Update stackup information.
1961
1978
 
1962
1979
  Parameters
@@ -2087,7 +2104,7 @@ class Stackup(LayerCollection):
2087
2104
 
2088
2105
  return True
2089
2106
 
2090
- def _get(self):
2107
+ def _get(self) -> Tuple[Dict, Dict, Dict, Dict]:
2091
2108
  """Get stackup information from layout.
2092
2109
 
2093
2110
  Returns
@@ -2116,27 +2133,27 @@ class Stackup(LayerCollection):
2116
2133
  roughness_models[name] = {}
2117
2134
  model = val.get_roughness_model("top")
2118
2135
  if model.type.name.endswith("GroissRoughnessModel"):
2119
- roughness_models[name]["GroissSurfaceRoughness"] = {"Roughness": model.get_Roughness.value}
2136
+ roughness_models[name]["GroissSurfaceRoughness"] = {"Roughness": Value(model.get_Roughness)}
2120
2137
  else:
2121
2138
  roughness_models[name]["HuraySurfaceRoughness"] = {
2122
- "HallHuraySurfaceRatio": model.get_nodule_radius().value,
2123
- "NoduleRadius": model.get_surface_ratio().value,
2139
+ "HallHuraySurfaceRatio": Value(model.get_nodule_radius()),
2140
+ "NoduleRadius": Value(model.get_surface_ratio()),
2124
2141
  }
2125
2142
  model = val.get_roughness_model("bottom")
2126
2143
  if model.type.name.endswith("GroissRoughnessModel"):
2127
- roughness_models[name]["GroissBottomSurfaceRoughness"] = {"Roughness": model.get_roughness().value}
2144
+ roughness_models[name]["GroissBottomSurfaceRoughness"] = {"Roughness": Value(model.get_roughness())}
2128
2145
  else:
2129
2146
  roughness_models[name]["HurayBottomSurfaceRoughness"] = {
2130
- "HallHuraySurfaceRatio": model.get_nodule_radius().value,
2131
- "NoduleRadius": model.get_surface_ratio().value,
2147
+ "HallHuraySurfaceRatio": Value(model.get_nodule_radius()),
2148
+ "NoduleRadius": Value(model.get_surface_ratio()),
2132
2149
  }
2133
2150
  model = val.get_roughness_model("side")
2134
2151
  if model.ToString().endswith("GroissRoughnessModel"):
2135
- roughness_models[name]["GroissSideSurfaceRoughness"] = {"Roughness": model.get_roughness().value}
2152
+ roughness_models[name]["GroissSideSurfaceRoughness"] = {"Roughness": Value(model.get_roughness())}
2136
2153
  else:
2137
2154
  roughness_models[name]["HuraySideSurfaceRoughness"] = {
2138
- "HallHuraySurfaceRatio": model.get_nodule_radius().value,
2139
- "NoduleRadius": model.get_surface_ratio().value,
2155
+ "HallHuraySurfaceRatio": Value(model.get_nodule_radius()),
2156
+ "NoduleRadius": Value(model.get_surface_ratio()),
2140
2157
  }
2141
2158
 
2142
2159
  non_stackup_layers = OrderedDict()
@@ -2159,7 +2176,7 @@ class Stackup(LayerCollection):
2159
2176
 
2160
2177
  return layers, materials, roughness_models, non_stackup_layers
2161
2178
 
2162
- def _add_materials_from_dictionary(self, material_dict):
2179
+ def _add_materials_from_dictionary(self, material_dict: Dict[str, Dict]) -> bool:
2163
2180
  materials = self.self._pedb.materials.materials
2164
2181
  for name, material_properties in material_dict.items():
2165
2182
  if "Conductivity" in material_properties:
@@ -2172,7 +2189,7 @@ class Stackup(LayerCollection):
2172
2189
  )
2173
2190
  return True
2174
2191
 
2175
- def _import_xml(self, file_path, rename=False):
2192
+ def _import_xml(self, file_path: str, rename: bool = False) -> bool:
2176
2193
  """Read external XML file and convert into JSON format.
2177
2194
 
2178
2195
  Parameters
@@ -2243,7 +2260,7 @@ class Stackup(LayerCollection):
2243
2260
  cfg = {"stackup": stackup_dict}
2244
2261
  return self._pedb.configuration.load(cfg, apply_file=True)
2245
2262
 
2246
- def _export_xml(self, file_path):
2263
+ def _export_xml(self, file_path: str) -> bool:
2247
2264
  """Export stackup information to an external XML file.
2248
2265
 
2249
2266
  Parameters
@@ -2293,7 +2310,7 @@ class Stackup(LayerCollection):
2293
2310
  write_pretty_xml(root, file_path)
2294
2311
  return True
2295
2312
 
2296
- def load(self, file_path, rename=False):
2313
+ def load(self, file_path: Union[str, Dict], rename: bool = False) -> bool:
2297
2314
  """Import stackup from a file.
2298
2315
 
2299
2316
  Supported formats: XML, CSV, JSON.
@@ -2332,14 +2349,14 @@ class Stackup(LayerCollection):
2332
2349
 
2333
2350
  def plot(
2334
2351
  self,
2335
- save_plot=None,
2336
- size=(2000, 1500),
2337
- plot_definitions=None,
2338
- first_layer=None,
2339
- last_layer=None,
2340
- scale_elevation=True,
2341
- show=True,
2342
- ):
2352
+ save_plot: Optional[str] = None,
2353
+ size: Tuple[int, int] = (2000, 1500),
2354
+ plot_definitions: Optional[Union[str, List[str]]] = None,
2355
+ first_layer: Optional[Union[str, "Layer"]] = None,
2356
+ last_layer: Optional[Union[str, "Layer"]] = None,
2357
+ scale_elevation: bool = True,
2358
+ show: bool = True,
2359
+ ) -> Any:
2343
2360
  """Plot the current stackup and optionally overlap padstack definitions.
2344
2361
 
2345
2362
  Only supports 'Laminate' and 'Overlapping' stackup types.