pyedb 0.53.0__py3-none-any.whl → 0.55.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 (119) hide show
  1. pyedb/__init__.py +1 -8
  2. pyedb/configuration/cfg_boundaries.py +69 -151
  3. pyedb/configuration/cfg_components.py +201 -460
  4. pyedb/configuration/cfg_data.py +4 -2
  5. pyedb/configuration/cfg_general.py +13 -36
  6. pyedb/configuration/cfg_modeler.py +2 -1
  7. pyedb/configuration/cfg_nets.py +21 -35
  8. pyedb/configuration/cfg_operations.py +22 -151
  9. pyedb/configuration/cfg_package_definition.py +56 -112
  10. pyedb/configuration/cfg_padstacks.py +292 -688
  11. pyedb/configuration/cfg_pin_groups.py +32 -79
  12. pyedb/configuration/cfg_ports_sources.py +20 -9
  13. pyedb/configuration/cfg_s_parameter_models.py +67 -172
  14. pyedb/configuration/cfg_setup.py +102 -295
  15. pyedb/configuration/configuration.py +66 -6
  16. pyedb/dotnet/database/cell/connectable.py +38 -9
  17. pyedb/dotnet/database/cell/hierarchy/component.py +28 -28
  18. pyedb/dotnet/database/cell/hierarchy/model.py +1 -1
  19. pyedb/dotnet/database/cell/layout.py +64 -3
  20. pyedb/dotnet/database/cell/layout_obj.py +3 -3
  21. pyedb/dotnet/database/cell/primitive/path.py +6 -8
  22. pyedb/dotnet/database/cell/primitive/primitive.py +10 -31
  23. pyedb/dotnet/database/cell/terminal/edge_terminal.py +2 -2
  24. pyedb/dotnet/database/cell/terminal/padstack_instance_terminal.py +1 -1
  25. pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
  26. pyedb/dotnet/database/cell/terminal/point_terminal.py +1 -1
  27. pyedb/dotnet/database/cell/terminal/terminal.py +26 -28
  28. pyedb/dotnet/database/cell/voltage_regulator.py +0 -21
  29. pyedb/dotnet/database/components.py +99 -91
  30. pyedb/dotnet/database/definition/component_def.py +4 -4
  31. pyedb/dotnet/database/definition/component_model.py +1 -1
  32. pyedb/dotnet/database/definition/package_def.py +2 -3
  33. pyedb/dotnet/database/dotnet/database.py +27 -218
  34. pyedb/dotnet/database/dotnet/primitive.py +16 -16
  35. pyedb/dotnet/database/edb_data/control_file.py +5 -5
  36. pyedb/dotnet/database/edb_data/hfss_extent_info.py +6 -6
  37. pyedb/dotnet/database/edb_data/layer_data.py +35 -35
  38. pyedb/dotnet/database/edb_data/padstacks_data.py +65 -90
  39. pyedb/dotnet/database/edb_data/primitives_data.py +5 -5
  40. pyedb/dotnet/database/edb_data/sources.py +6 -6
  41. pyedb/dotnet/database/edb_data/variables.py +8 -4
  42. pyedb/dotnet/database/geometry/point_data.py +14 -10
  43. pyedb/dotnet/database/geometry/polygon_data.py +3 -5
  44. pyedb/dotnet/database/hfss.py +50 -52
  45. pyedb/dotnet/database/layout_validation.py +14 -11
  46. pyedb/dotnet/database/materials.py +10 -11
  47. pyedb/dotnet/database/modeler.py +104 -101
  48. pyedb/dotnet/database/nets.py +20 -23
  49. pyedb/dotnet/database/padstack.py +156 -84
  50. pyedb/dotnet/database/sim_setup_data/data/settings.py +24 -0
  51. pyedb/dotnet/database/sim_setup_data/io/siwave.py +26 -1
  52. pyedb/dotnet/database/siwave.py +47 -47
  53. pyedb/dotnet/database/stackup.py +152 -87
  54. pyedb/dotnet/database/utilities/heatsink.py +4 -4
  55. pyedb/dotnet/database/utilities/obj_base.py +3 -3
  56. pyedb/dotnet/database/utilities/simulation_setup.py +2 -2
  57. pyedb/dotnet/database/utilities/value.py +116 -0
  58. pyedb/dotnet/edb.py +248 -170
  59. pyedb/edb_logger.py +12 -27
  60. pyedb/extensions/via_design_backend.py +6 -3
  61. pyedb/generic/design_types.py +68 -21
  62. pyedb/generic/general_methods.py +0 -120
  63. pyedb/generic/process.py +44 -108
  64. pyedb/generic/settings.py +75 -19
  65. pyedb/grpc/__init__.py +0 -0
  66. pyedb/grpc/database/components.py +55 -17
  67. pyedb/grpc/database/control_file.py +5 -5
  68. pyedb/grpc/database/definition/materials.py +24 -31
  69. pyedb/grpc/database/definition/package_def.py +18 -18
  70. pyedb/grpc/database/definition/padstack_def.py +104 -51
  71. pyedb/grpc/database/geometry/arc_data.py +7 -5
  72. pyedb/grpc/database/geometry/point_3d_data.py +8 -7
  73. pyedb/grpc/database/geometry/polygon_data.py +4 -3
  74. pyedb/grpc/database/hierarchy/component.py +43 -38
  75. pyedb/grpc/database/hierarchy/pin_pair_model.py +15 -14
  76. pyedb/grpc/database/hierarchy/pingroup.py +9 -9
  77. pyedb/grpc/database/layers/stackup_layer.py +45 -44
  78. pyedb/grpc/database/layout/layout.py +17 -13
  79. pyedb/grpc/database/layout/voltage_regulator.py +7 -7
  80. pyedb/grpc/database/layout_validation.py +16 -15
  81. pyedb/grpc/database/modeler.py +60 -58
  82. pyedb/grpc/database/net/net.py +15 -14
  83. pyedb/grpc/database/nets.py +112 -31
  84. pyedb/grpc/database/padstacks.py +303 -190
  85. pyedb/grpc/database/ports/ports.py +5 -6
  86. pyedb/grpc/database/primitive/bondwire.py +8 -7
  87. pyedb/grpc/database/primitive/circle.py +4 -4
  88. pyedb/grpc/database/primitive/padstack_instance.py +191 -23
  89. pyedb/grpc/database/primitive/path.py +7 -7
  90. pyedb/grpc/database/primitive/polygon.py +3 -3
  91. pyedb/grpc/database/primitive/primitive.py +13 -17
  92. pyedb/grpc/database/primitive/rectangle.py +13 -13
  93. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +1 -1
  94. pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +10 -0
  95. pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +17 -1
  96. pyedb/grpc/database/siwave.py +31 -25
  97. pyedb/grpc/database/source_excitations.py +335 -233
  98. pyedb/grpc/database/stackup.py +165 -148
  99. pyedb/grpc/database/terminal/bundle_terminal.py +18 -8
  100. pyedb/grpc/database/terminal/edge_terminal.py +10 -0
  101. pyedb/grpc/database/terminal/padstack_instance_terminal.py +16 -5
  102. pyedb/grpc/database/terminal/pingroup_terminal.py +12 -11
  103. pyedb/grpc/database/terminal/point_terminal.py +4 -3
  104. pyedb/grpc/database/terminal/terminal.py +9 -9
  105. pyedb/grpc/database/utility/value.py +109 -0
  106. pyedb/grpc/database/utility/xml_control_file.py +5 -5
  107. pyedb/grpc/edb.py +130 -63
  108. pyedb/grpc/edb_init.py +3 -10
  109. pyedb/grpc/rpc_session.py +10 -10
  110. pyedb/libraries/common.py +366 -0
  111. pyedb/libraries/rf_libraries/base_functions.py +1358 -0
  112. pyedb/libraries/rf_libraries/planar_antennas.py +628 -0
  113. pyedb/misc/decorators.py +61 -0
  114. pyedb/misc/misc.py +0 -13
  115. pyedb/siwave.py +2 -2
  116. {pyedb-0.53.0.dist-info → pyedb-0.55.0.dist-info}/METADATA +2 -3
  117. {pyedb-0.53.0.dist-info → pyedb-0.55.0.dist-info}/RECORD +119 -112
  118. {pyedb-0.53.0.dist-info → pyedb-0.55.0.dist-info}/WHEEL +0 -0
  119. {pyedb-0.53.0.dist-info → pyedb-0.55.0.dist-info}/licenses/LICENSE +0 -0
@@ -23,7 +23,9 @@
23
23
  """
24
24
  This module contains the `EdbPadstacks` class.
25
25
  """
26
+ from collections import defaultdict
26
27
  import math
28
+ from typing import Dict, List
27
29
  import warnings
28
30
 
29
31
  import numpy as np
@@ -82,7 +84,7 @@ class EdbPadstacks(object):
82
84
  @property
83
85
  def _edb(self):
84
86
  """ """
85
- return self._pedb.edb_api
87
+ return self._pedb.core
86
88
 
87
89
  def _get_edb_value(self, value):
88
90
  return self._pedb.edb_value(value)
@@ -126,15 +128,15 @@ class EdbPadstacks(object):
126
128
  """
127
129
 
128
130
  if val == 0:
129
- return self._edb.definition.PadType.RegularPad
131
+ return self._edb.Definition.PadType.RegularPad
130
132
  elif val == 1:
131
- return self._edb.definition.PadType.AntiPad
133
+ return self._edb.Definition.PadType.AntiPad
132
134
  elif val == 2:
133
- return self._edb.definition.PadType.ThermalPad
135
+ return self._edb.Definition.PadType.ThermalPad
134
136
  elif val == 3:
135
- return self._edb.definition.PadType.Hole
137
+ return self._edb.Definition.PadType.Hole
136
138
  elif val == 4:
137
- return self._edb.definition.PadType.UnknownGeomType
139
+ return self._edb.Definition.PadType.UnknownGeomType
138
140
  else:
139
141
  return val
140
142
 
@@ -151,29 +153,29 @@ class EdbPadstacks(object):
151
153
  EDB.PadGeometryType enumerator value.
152
154
  """
153
155
  if val == 0:
154
- return self._edb.definition.PadGeometryType.NoGeometry
156
+ return self._edb.Definition.PadGeometryType.NoGeometry
155
157
  elif val == 1:
156
- return self._edb.definition.PadGeometryType.Circle
158
+ return self._edb.Definition.PadGeometryType.Circle
157
159
  elif val == 2:
158
- return self._edb.definition.PadGeometryType.Square
160
+ return self._edb.Definition.PadGeometryType.Square
159
161
  elif val == 3:
160
- return self._edb.definition.PadGeometryType.Rectangle
162
+ return self._edb.Definition.PadGeometryType.Rectangle
161
163
  elif val == 4:
162
- return self._edb.definition.PadGeometryType.Oval
164
+ return self._edb.Definition.PadGeometryType.Oval
163
165
  elif val == 5:
164
- return self._edb.definition.PadGeometryType.Bullet
166
+ return self._edb.Definition.PadGeometryType.Bullet
165
167
  elif val == 6:
166
- return self._edb.definition.PadGeometryType.NSidedPolygon
168
+ return self._edb.Definition.PadGeometryType.NSidedPolygon
167
169
  elif val == 7:
168
- return self._edb.definition.PadGeometryType.Polygon
170
+ return self._edb.Definition.PadGeometryType.Polygon
169
171
  elif val == 8:
170
- return self._edb.definition.PadGeometryType.Round45
172
+ return self._edb.Definition.PadGeometryType.Round45
171
173
  elif val == 9:
172
- return self._edb.definition.PadGeometryType.Round90
174
+ return self._edb.Definition.PadGeometryType.Round90
173
175
  elif val == 10:
174
- return self._edb.definition.PadGeometryType.Square45
176
+ return self._edb.Definition.PadGeometryType.Square45
175
177
  elif val == 11:
176
- return self._edb.definition.PadGeometryType.Square90
178
+ return self._edb.Definition.PadGeometryType.Square90
177
179
  else:
178
180
  return val
179
181
 
@@ -187,10 +189,10 @@ class EdbPadstacks(object):
187
189
  List of definitions via padstack definitions.
188
190
 
189
191
  """
190
- if len(self._definitions) == len(self._pedb.padstack_defs):
192
+ if len(self._definitions) == len(list(self._pedb._db.PadstackDefs)):
191
193
  return self._definitions
192
194
  self._definitions = {}
193
- for padstackdef in self._pedb.padstack_defs:
195
+ for padstackdef in list(self._pedb._db.PadstackDefs):
194
196
  PadStackData = padstackdef.GetData()
195
197
  if len(PadStackData.GetLayerNames()) >= 1:
196
198
  self._definitions[padstackdef.GetName()] = EDBPadstack(padstackdef, self)
@@ -329,11 +331,11 @@ class EdbPadstacks(object):
329
331
 
330
332
  class PadType:
331
333
  (RegularPad, AntiPad, ThermalPad, Hole, UnknownGeomType) = (
332
- self._edb.definition.PadType.RegularPad,
333
- self._edb.definition.PadType.AntiPad,
334
- self._edb.definition.PadType.ThermalPad,
335
- self._edb.definition.PadType.Hole,
336
- self._edb.definition.PadType.UnknownGeomType,
334
+ self._edb.Definition.PadType.RegularPad,
335
+ self._edb.Definition.PadType.AntiPad,
336
+ self._edb.Definition.PadType.ThermalPad,
337
+ self._edb.Definition.PadType.Hole,
338
+ self._edb.Definition.PadType.UnknownGeomType,
337
339
  )
338
340
 
339
341
  return PadType
@@ -372,32 +374,32 @@ class EdbPadstacks(object):
372
374
  Name of the padstack if the operation is successful.
373
375
  """
374
376
 
375
- PadStack = self._edb.definition.PadstackDef.Create(self._layout.cell.GetDatabase(), padstackname)
376
- new_PadStackData = self._edb.definition.PadstackDefData.Create()
377
+ PadStack = self._edb.Definition.PadstackDef.Create(self._layout.cell.GetDatabase(), padstackname)
378
+ new_PadStackData = self._edb.Definition.PadstackDefData.Create()
377
379
  list_values = convert_py_list_to_net_list(
378
380
  [self._get_edb_value(holediam), self._get_edb_value(paddiam), self._get_edb_value(antipaddiam)]
379
381
  )
380
382
  value0 = self._get_edb_value(0.0)
381
383
  new_PadStackData.SetHoleParameters(
382
- self._edb.definition.PadGeometryType.Circle,
384
+ self._edb.Definition.PadGeometryType.Circle,
383
385
  list_values,
384
386
  value0,
385
387
  value0,
386
388
  value0,
387
389
  )
388
- new_PadStackData.SetHoleRange(self._edb.definition.PadstackHoleRange.UpperPadToLowerPad)
390
+ new_PadStackData.SetHoleRange(self._edb.Definition.PadstackHoleRange.UpperPadToLowerPad)
389
391
  layers = list(self._pedb.stackup.signal_layers.keys())
390
392
  if not startlayer:
391
393
  startlayer = layers[0]
392
394
  if not endlayer:
393
395
  endlayer = layers[len(layers) - 1]
394
396
 
395
- antipad_shape = self._edb.definition.PadGeometryType.Circle
397
+ antipad_shape = self._edb.Definition.PadGeometryType.Circle
396
398
  started = False
397
399
  new_PadStackData.SetPadParameters(
398
400
  "Default",
399
- self._edb.definition.PadType.RegularPad,
400
- self._edb.definition.PadGeometryType.Circle,
401
+ self._edb.Definition.PadType.RegularPad,
402
+ self._edb.Definition.PadGeometryType.Circle,
401
403
  convert_py_list_to_net_list([self._get_edb_value(paddiam)]),
402
404
  value0,
403
405
  value0,
@@ -406,7 +408,7 @@ class EdbPadstacks(object):
406
408
 
407
409
  new_PadStackData.SetPadParameters(
408
410
  "Default",
409
- self._edb.definition.PadType.AntiPad,
411
+ self._edb.Definition.PadType.AntiPad,
410
412
  antipad_shape,
411
413
  convert_py_list_to_net_list([self._get_edb_value(antipaddiam)]),
412
414
  value0,
@@ -421,8 +423,8 @@ class EdbPadstacks(object):
421
423
  if started:
422
424
  new_PadStackData.SetPadParameters(
423
425
  layer,
424
- self._edb.definition.PadType.RegularPad,
425
- self._edb.definition.PadGeometryType.Circle,
426
+ self._edb.Definition.PadType.RegularPad,
427
+ self._edb.Definition.PadGeometryType.Circle,
426
428
  convert_py_list_to_net_list([self._get_edb_value(paddiam)]),
427
429
  value0,
428
430
  value0,
@@ -430,7 +432,7 @@ class EdbPadstacks(object):
430
432
  )
431
433
  new_PadStackData.SetPadParameters(
432
434
  layer,
433
- self._edb.definition.PadType.AntiPad,
435
+ self._edb.Definition.PadType.AntiPad,
434
436
  antipad_shape,
435
437
  convert_py_list_to_net_list([self._get_edb_value(antipaddiam)]),
436
438
  value0,
@@ -491,13 +493,13 @@ class EdbPadstacks(object):
491
493
 
492
494
  else:
493
495
  psdef = padstackInst._edb_object.GetPadstackDef()
494
- newdefdata = self._edb.definition.PadstackDefData(psdef.GetData())
495
- newdefdata.SetSolderBallShape(self._edb.definition.SolderballShape.Cylinder)
496
+ newdefdata = self._edb.Definition.PadstackDefData(psdef.GetData())
497
+ newdefdata.SetSolderBallShape(self._edb.Definition.SolderballShape.Cylinder)
496
498
  newdefdata.SetSolderBallParameter(self._get_edb_value(ballDiam), self._get_edb_value(ballDiam))
497
499
  sball_placement = (
498
- self._edb.definition.SolderballPlacement.AbovePadstack
500
+ self._edb.Definition.SolderballPlacement.AbovePadstack
499
501
  if isTopPlaced
500
- else self._edb.definition.SolderballPlacement.BelowPadstack
502
+ else self._edb.Definition.SolderballPlacement.BelowPadstack
501
503
  )
502
504
  newdefdata.SetSolderBallPlacement(sball_placement)
503
505
  psdef.SetData(newdefdata)
@@ -558,7 +560,7 @@ class EdbPadstacks(object):
558
560
  if self._port_exist(port_name):
559
561
  port_name = generate_unique_name(port_name, n=2)
560
562
  self._logger.info("An existing port already has this same name. Renaming to {}.".format(port_name))
561
- self._edb.cell.terminal.PadstackInstanceTerminal.Create(
563
+ self._edb.Cell.Terminal.PadstackInstanceTerminal.Create(
562
564
  self._active_layout,
563
565
  padstackinstance.GetNet(),
564
566
  port_name,
@@ -631,7 +633,7 @@ class EdbPadstacks(object):
631
633
  else:
632
634
  if not isinstance(pin, EDBPadstackInstance):
633
635
  pin = EDBPadstackInstance(pin, self._pedb)
634
- padparams = self._edb.definition.PadstackDefData(
636
+ padparams = self._edb.Definition.PadstackDefData(
635
637
  pin._edb_object.GetPadstackDef().GetData()
636
638
  ).GetPadParametersValue(layername, self.int_to_pad_type(pad_type))
637
639
  if padparams[2]:
@@ -642,12 +644,12 @@ class EdbPadstacks(object):
642
644
  rotation = padparams[5].ToDouble()
643
645
  return geometry_type, parameters, offset_x, offset_y, rotation
644
646
  else:
645
- if isinstance(pin, self._edb.definition.PadstackDef):
646
- padparams = self._edb.definition.PadstackDefData(pin.GetData()).GetPolygonalPadParameters(
647
+ if isinstance(pin, self._edb.Definition.PadstackDef):
648
+ padparams = self._edb.Definition.PadstackDefData(pin.GetData()).GetPolygonalPadParameters(
647
649
  layername, self.int_to_pad_type(pad_type)
648
650
  )
649
651
  else:
650
- padparams = self._edb.definition.PadstackDefData(
652
+ padparams = self._edb.Definition.PadstackDefData(
651
653
  pin._edb_object.GetPadstackDef().GetData()
652
654
  ).GetPolygonalPadParameters(layername, self.int_to_pad_type(pad_type))
653
655
 
@@ -680,7 +682,7 @@ class EdbPadstacks(object):
680
682
  """
681
683
  if self.definitions:
682
684
  for padstack in list(self.definitions.values()):
683
- cloned_padstack_data = self._edb.definition.PadstackDefData(padstack.edb_padstack.GetData())
685
+ cloned_padstack_data = self._edb.Definition.PadstackDefData(padstack.edb_padstack.GetData())
684
686
  layers_name = cloned_padstack_data.GetLayerNames()
685
687
  all_succeed = True
686
688
  for layer in layers_name:
@@ -691,11 +693,11 @@ class EdbPadstacks(object):
691
693
  params = convert_py_list_to_net_list(
692
694
  [self._pedb.edb_value(value)] * len(parameters)
693
695
  ) # pragma no cover
694
- geom = self._edb.definition.PadGeometryType.Circle
696
+ geom = self._edb.Definition.PadGeometryType.Circle
695
697
  offset_x = self._pedb.edb_value(offset_x)
696
698
  offset_y = self._pedb.edb_value(offset_y)
697
699
  rot = self._pedb.edb_value(rot)
698
- antipad = self._edb.definition.PadType.AntiPad
700
+ antipad = self._edb.Definition.PadType.AntiPad
699
701
  if cloned_padstack_data.SetPadParameters(
700
702
  layer, antipad, geom, params, offset_x, offset_y, rot
701
703
  ): # pragma no cover
@@ -943,9 +945,9 @@ class EdbPadstacks(object):
943
945
  if not padstackname:
944
946
  padstackname = generate_unique_name("VIA")
945
947
  # assert not self.isreadonly, "Write Functions are not available within AEDT"
946
- padstackData = self._edb.definition.PadstackDefData.Create()
948
+ padstackData = self._edb.Definition.PadstackDefData.Create()
947
949
  if has_hole and not polygon_hole:
948
- ptype = self._edb.definition.PadGeometryType.Circle
950
+ ptype = self._edb.Definition.PadGeometryType.Circle
949
951
  hole_param = Array[type(holediam)]([holediam])
950
952
  padstackData.SetHoleParameters(ptype, hole_param, value0, value0, value0)
951
953
  padstackData.SetHolePlatingPercentage(self._get_edb_value(20.0))
@@ -964,7 +966,7 @@ class EdbPadstacks(object):
964
966
  padstackData.SetPolygonalHoleParameters(hole_param, value0, value0, value0)
965
967
  padstackData.SetHolePlatingPercentage(self._get_edb_value(20.0))
966
968
  else:
967
- ptype = self._edb.definition.PadGeometryType.NoGeometry
969
+ ptype = self._edb.Definition.PadGeometryType.NoGeometry
968
970
 
969
971
  x_size = self._get_edb_value(x_size)
970
972
  y_size = self._get_edb_value(y_size)
@@ -980,13 +982,13 @@ class EdbPadstacks(object):
980
982
  anti_pad_y_size = self._get_edb_value(anti_pad_y_size)
981
983
 
982
984
  if hole_range == "through": # pragma no cover
983
- padstackData.SetHoleRange(self._edb.definition.PadstackHoleRange.Through)
985
+ padstackData.SetHoleRange(self._edb.Definition.PadstackHoleRange.Through)
984
986
  elif hole_range == "begin_on_upper_pad": # pragma no cover
985
- padstackData.SetHoleRange(self._edb.definition.PadstackHoleRange.BeginOnUpperPad)
987
+ padstackData.SetHoleRange(self._edb.Definition.PadstackHoleRange.BeginOnUpperPad)
986
988
  elif hole_range == "end_on_lower_pad": # pragma no cover
987
- padstackData.SetHoleRange(self._edb.definition.PadstackHoleRange.EndOnLowerPad)
989
+ padstackData.SetHoleRange(self._edb.Definition.PadstackHoleRange.EndOnLowerPad)
988
990
  elif hole_range == "upper_pad_to_lower_pad": # pragma no cover
989
- padstackData.SetHoleRange(self._edb.definition.PadstackHoleRange.UpperPadToLowerPad)
991
+ padstackData.SetHoleRange(self._edb.Definition.PadstackHoleRange.UpperPadToLowerPad)
990
992
  else: # pragma no cover
991
993
  self._logger.error("Unknown padstack hole range")
992
994
  padstackData.SetMaterial("copper")
@@ -997,10 +999,10 @@ class EdbPadstacks(object):
997
999
  layers = layers[: layers.index(stop_layer) + 1]
998
1000
  pad_array = Array[type(paddiam)]([paddiam])
999
1001
  if pad_shape == "Circle": # pragma no cover
1000
- pad_shape = self._edb.definition.PadGeometryType.Circle
1002
+ pad_shape = self._edb.Definition.PadGeometryType.Circle
1001
1003
  elif pad_shape == "Rectangle": # pragma no cover
1002
1004
  pad_array = Array[type(x_size)]([x_size, y_size])
1003
- pad_shape = self._edb.definition.PadGeometryType.Rectangle
1005
+ pad_shape = self._edb.Definition.PadGeometryType.Rectangle
1004
1006
  elif pad_shape == "Polygon":
1005
1007
  if isinstance(pad_polygon, list):
1006
1008
  _poly = self._pedb.modeler.create_polygon(pad_polygon, layers[0], net_name="dummy")
@@ -1013,10 +1015,10 @@ class EdbPadstacks(object):
1013
1015
  pad_array = pad_polygon
1014
1016
  if antipad_shape == "Bullet": # pragma no cover
1015
1017
  antipad_array = Array[type(x_size)]([x_size, y_size, corner_radius])
1016
- antipad_shape = self._edb.definition.PadGeometryType.Bullet
1018
+ antipad_shape = self._edb.Definition.PadGeometryType.Bullet
1017
1019
  elif antipad_shape == "Rectangle": # pragma no cover
1018
1020
  antipad_array = Array[type(anti_pad_x_size)]([anti_pad_x_size, anti_pad_y_size])
1019
- antipad_shape = self._edb.definition.PadGeometryType.Rectangle
1021
+ antipad_shape = self._edb.Definition.PadGeometryType.Rectangle
1020
1022
  elif antipad_shape == "Polygon":
1021
1023
  if isinstance(antipad_polygon, list):
1022
1024
  _poly = self._pedb.modeler.create_polygon(antipad_polygon, layers[0], net_name="dummy")
@@ -1029,14 +1031,14 @@ class EdbPadstacks(object):
1029
1031
  antipad_array = antipad_polygon
1030
1032
  else: # pragma no cover
1031
1033
  antipad_array = Array[type(antipaddiam)]([antipaddiam])
1032
- antipad_shape = self._edb.definition.PadGeometryType.Circle
1034
+ antipad_shape = self._edb.Definition.PadGeometryType.Circle
1033
1035
  if add_default_layer: # pragma no cover
1034
1036
  layers = layers + ["Default"]
1035
1037
  if antipad_shape == "Polygon" and pad_shape == "Polygon":
1036
1038
  for layer in layers:
1037
1039
  padstackData.SetPolygonalPadParameters(
1038
1040
  layer,
1039
- self._edb.definition.PadType.RegularPad,
1041
+ self._edb.Definition.PadType.RegularPad,
1040
1042
  pad_array._edb_object,
1041
1043
  pad_offset_x,
1042
1044
  pad_offset_y,
@@ -1044,7 +1046,7 @@ class EdbPadstacks(object):
1044
1046
  )
1045
1047
  padstackData.SetPolygonalPadParameters(
1046
1048
  layer,
1047
- self._edb.definition.PadType.AntiPad,
1049
+ self._edb.Definition.PadType.AntiPad,
1048
1050
  antipad_array._edb_object,
1049
1051
  pad_offset_x,
1050
1052
  pad_offset_y,
@@ -1054,7 +1056,7 @@ class EdbPadstacks(object):
1054
1056
  for layer in layers:
1055
1057
  padstackData.SetPadParameters(
1056
1058
  layer,
1057
- self._edb.definition.PadType.RegularPad,
1059
+ self._edb.Definition.PadType.RegularPad,
1058
1060
  pad_shape,
1059
1061
  pad_array,
1060
1062
  pad_offset_x,
@@ -1064,7 +1066,7 @@ class EdbPadstacks(object):
1064
1066
 
1065
1067
  padstackData.SetPadParameters(
1066
1068
  layer,
1067
- self._edb.definition.PadType.AntiPad,
1069
+ self._edb.Definition.PadType.AntiPad,
1068
1070
  antipad_shape,
1069
1071
  antipad_array,
1070
1072
  offset_x,
@@ -1072,7 +1074,7 @@ class EdbPadstacks(object):
1072
1074
  rotation,
1073
1075
  )
1074
1076
 
1075
- padstackDefinition = self._edb.definition.PadstackDef.Create(self.db, padstackname)
1077
+ padstackDefinition = self._edb.Definition.PadstackDef.Create(self.db, padstackname)
1076
1078
  padstackDefinition.SetData(padstackData)
1077
1079
  self._logger.info("Padstack %s create correctly", padstackname)
1078
1080
  return padstackname
@@ -1121,12 +1123,12 @@ class EdbPadstacks(object):
1121
1123
  Name of the new padstack.
1122
1124
  """
1123
1125
  p1 = self.definitions[target_padstack_name].edb_padstack.GetData()
1124
- new_padstack_definition_data = self._edb.definition.PadstackDefData(p1)
1126
+ new_padstack_definition_data = self._edb.Definition.PadstackDefData(p1)
1125
1127
 
1126
1128
  if not new_padstack_name:
1127
1129
  new_padstack_name = generate_unique_name(target_padstack_name)
1128
1130
 
1129
- padstack_definition = self._edb.definition.PadstackDef.Create(self.db, new_padstack_name)
1131
+ padstack_definition = self._edb.Definition.PadstackDef.Create(self.db, new_padstack_name)
1130
1132
  padstack_definition.SetData(new_padstack_definition_data)
1131
1133
 
1132
1134
  return new_padstack_name
@@ -1175,7 +1177,8 @@ class EdbPadstacks(object):
1175
1177
  for pad in list(self.definitions.keys()):
1176
1178
  if pad == definition_name:
1177
1179
  padstack = self.definitions[pad].edb_padstack
1178
- position = self._edb.geometry.point_data(position[0], position[1])
1180
+ # position = self._edb.Geometry.PointData(position[0], position[1])
1181
+ position = self._pedb.pedb_class.database.geometry.point_data.PointData.create_from_xy(self._pedb, *position)
1179
1182
  net = self._pedb.nets.find_or_create_net(net_name)
1180
1183
  rotation = (
1181
1184
  self._get_edb_value(rotation * math.pi / 180)
@@ -1202,20 +1205,20 @@ class EdbPadstacks(object):
1202
1205
  if solderlayer:
1203
1206
  solderlayer = sign_layers_values[solderlayer]._edb_layer
1204
1207
  if padstack:
1205
- padstack_instance = self._edb.cell.primitive.padstack_instance.create(
1208
+ padstack_instance = self._edb.Cell.Primitive.PadstackInstance.Create(
1206
1209
  self._active_layout,
1207
- net,
1210
+ net._edb_object,
1208
1211
  via_name,
1209
1212
  padstack,
1210
- position,
1213
+ position._edb_object,
1211
1214
  rotation,
1212
1215
  fromlayer,
1213
1216
  tolayer,
1214
1217
  solderlayer,
1215
1218
  None,
1216
1219
  )
1217
- padstack_instance.is_layout_pin = is_pin
1218
- py_padstack_instance = EDBPadstackInstance(padstack_instance.api_object, self._pedb)
1220
+ padstack_instance.SetIsLayoutPin(is_pin)
1221
+ py_padstack_instance = EDBPadstackInstance(padstack_instance, self._pedb)
1219
1222
 
1220
1223
  return py_padstack_instance
1221
1224
  else:
@@ -1290,12 +1293,12 @@ class EdbPadstacks(object):
1290
1293
  bool
1291
1294
  ``True`` if successful.
1292
1295
  """
1293
- pad_type = self._edb.definition.PadType.RegularPad
1294
- pad_geo = self._edb.definition.PadGeometryType.Circle
1296
+ pad_type = self._edb.Definition.PadType.RegularPad
1297
+ pad_geo = self._edb.Definition.PadGeometryType.Circle
1295
1298
  vals = self._get_edb_value(0)
1296
1299
  params = convert_py_list_to_net_list([self._get_edb_value(0)])
1297
1300
  p1 = self.definitions[padstack_name].edb_padstack.GetData()
1298
- newPadstackDefinitionData = self._edb.definition.PadstackDefData(p1)
1301
+ newPadstackDefinitionData = self._edb.Definition.PadstackDefData(p1)
1299
1302
 
1300
1303
  if not layer_name:
1301
1304
  layer_name = list(self._pedb.stackup.signal_layers.keys())
@@ -1358,11 +1361,11 @@ class EdbPadstacks(object):
1358
1361
  ``True`` if successful.
1359
1362
  """
1360
1363
  shape_dict = {
1361
- "Circle": self._edb.definition.PadGeometryType.Circle,
1362
- "Square": self._edb.definition.PadGeometryType.Square,
1363
- "Rectangle": self._edb.definition.PadGeometryType.Rectangle,
1364
- "Oval": self._edb.definition.PadGeometryType.Oval,
1365
- "Bullet": self._edb.definition.PadGeometryType.Bullet,
1364
+ "Circle": self._edb.Definition.PadGeometryType.Circle,
1365
+ "Square": self._edb.Definition.PadGeometryType.Square,
1366
+ "Rectangle": self._edb.Definition.PadGeometryType.Rectangle,
1367
+ "Oval": self._edb.Definition.PadGeometryType.Oval,
1368
+ "Bullet": self._edb.Definition.PadGeometryType.Bullet,
1366
1369
  }
1367
1370
  pad_shape = shape_dict[pad_shape]
1368
1371
  if not isinstance(pad_params, list):
@@ -1381,7 +1384,7 @@ class EdbPadstacks(object):
1381
1384
  antipad_rotation = self._get_edb_value(antipad_rotation)
1382
1385
 
1383
1386
  p1 = self.definitions[padstack_name].edb_padstack.GetData()
1384
- new_padstack_def = self._edb.definition.PadstackDefData(p1)
1387
+ new_padstack_def = self._edb.Definition.PadstackDefData(p1)
1385
1388
  if not layer_name:
1386
1389
  layer_name = list(self._pedb.stackup.signal_layers.keys())
1387
1390
  elif isinstance(layer_name, str):
@@ -1389,7 +1392,7 @@ class EdbPadstacks(object):
1389
1392
  for layer in layer_name:
1390
1393
  new_padstack_def.SetPadParameters(
1391
1394
  layer,
1392
- self._edb.definition.PadType.RegularPad,
1395
+ self._edb.Definition.PadType.RegularPad,
1393
1396
  pad_shape,
1394
1397
  pad_params,
1395
1398
  pad_x_offset,
@@ -1398,7 +1401,7 @@ class EdbPadstacks(object):
1398
1401
  )
1399
1402
  new_padstack_def.SetPadParameters(
1400
1403
  layer,
1401
- self._edb.definition.PadType.AntiPad,
1404
+ self._edb.Definition.PadType.AntiPad,
1402
1405
  antipad_shape,
1403
1406
  antipad_params,
1404
1407
  antipad_x_offset,
@@ -1871,3 +1874,72 @@ class EdbPadstacks(object):
1871
1874
  all_instances[item].delete()
1872
1875
 
1873
1876
  return True
1877
+
1878
+ @staticmethod
1879
+ def dbscan(
1880
+ padstack: Dict[int, List[float]], max_distance: float = 1e-3, min_samples: int = 5
1881
+ ) -> Dict[int, List[str]]:
1882
+ """
1883
+ density based spatial clustering for padstack instances
1884
+
1885
+ Parameters
1886
+ ----------
1887
+ padstack : dict.
1888
+ padstack id: [x, y]
1889
+
1890
+ max_distance: float
1891
+ maximum distance between two points to be included in one cluster
1892
+
1893
+ min_samples: int
1894
+ minimum number of points that a cluster must have
1895
+
1896
+ Returns
1897
+ -------
1898
+ dict
1899
+ clusters {cluster label: [padstack ids]} <
1900
+ """
1901
+
1902
+ padstack_ids = list(padstack.keys())
1903
+ xy_array = np.array([padstack[pid] for pid in padstack_ids])
1904
+ n = len(padstack_ids)
1905
+
1906
+ labels = -1 * np.ones(n, dtype=int)
1907
+ visited = np.zeros(n, dtype=bool)
1908
+ cluster_id = 0
1909
+
1910
+ def region_query(point_idx):
1911
+ distances = np.linalg.norm(xy_array - xy_array[point_idx], axis=1)
1912
+ return np.where(distances <= max_distance)[0]
1913
+
1914
+ def expand_cluster(point_idx, neighbors):
1915
+ nonlocal cluster_id
1916
+ labels[point_idx] = cluster_id
1917
+ i = 0
1918
+ while i < len(neighbors):
1919
+ neighbor_idx = neighbors[i]
1920
+ if not visited[neighbor_idx]:
1921
+ visited[neighbor_idx] = True
1922
+ neighbor_neighbors = region_query(neighbor_idx)
1923
+ if len(neighbor_neighbors) >= min_samples:
1924
+ neighbors = np.concatenate((neighbors, neighbor_neighbors))
1925
+ if labels[neighbor_idx] == -1:
1926
+ labels[neighbor_idx] = cluster_id
1927
+ i += 1
1928
+
1929
+ for point_idx in range(n):
1930
+ if visited[point_idx]:
1931
+ continue
1932
+ visited[point_idx] = True
1933
+ neighbors = region_query(point_idx)
1934
+ if len(neighbors) < min_samples:
1935
+ labels[point_idx] = -1
1936
+ else:
1937
+ expand_cluster(point_idx, neighbors)
1938
+ cluster_id += 1
1939
+
1940
+ # group point IDs by label
1941
+ clusters = defaultdict(list)
1942
+ for i, label in enumerate(labels):
1943
+ clusters[int(label)].append(padstack_ids[i])
1944
+
1945
+ return dict(clusters)
@@ -19,6 +19,7 @@
19
19
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
+ import warnings
22
23
 
23
24
  from pyedb.dotnet.database.sim_setup_data.data.adaptive_frequency_data import (
24
25
  AdaptiveFrequencyData,
@@ -901,6 +902,24 @@ class HfssSolverSettings(object):
901
902
  def enhanced_low_freq_accuracy(self):
902
903
  """Whether to enable legacy low-frequency sampling.
903
904
 
905
+ .. deprecated:: pyedb 0.54.0
906
+ Use :func:`enhanced_low_frequency_accuracy` instead.
907
+
908
+ Returns
909
+ -------
910
+ bool
911
+ ``True`` if low frequency accuracy is used, ``False`` otherwise.
912
+ """
913
+ warnings.warn(
914
+ "`enhanced_low_freq_accuracy` is deprecated, use `enhanced_low_frequency_accuracy` instead.",
915
+ DeprecationWarning,
916
+ )
917
+ return self._hfss_solver_settings.EnhancedLowFreqAccuracy
918
+
919
+ @property
920
+ def enhanced_low_frequency_accuracy(self):
921
+ """Whether to enable legacy low-frequency sampling.
922
+
904
923
  Returns
905
924
  -------
906
925
  bool
@@ -913,6 +932,11 @@ class HfssSolverSettings(object):
913
932
  self._hfss_solver_settings.EnhancedLowFreqAccuracy = value
914
933
  self._parent._update_setup()
915
934
 
935
+ @enhanced_low_frequency_accuracy.setter
936
+ def enhanced_low_frequency_accuracy(self, value):
937
+ self._hfss_solver_settings.EnhancedLowFreqAccuracy = value
938
+ self._parent._update_setup()
939
+
916
940
  @property
917
941
  def order_basis(self):
918
942
  """Order of the basic functions for HFSS.
@@ -19,6 +19,7 @@
19
19
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
+ import warnings
22
23
 
23
24
 
24
25
  def _parse_value(v):
@@ -92,7 +93,7 @@ class AdvancedSettings(SettingsBase):
92
93
  def __init__(self, parent):
93
94
  super().__init__(parent)
94
95
  self.defaults = {
95
- "automatic_mesh": True,
96
+ "mesh_automatic": True,
96
97
  "ignore_non_functional_pads": True,
97
98
  "include_coplane_coupling": True,
98
99
  "include_fringe_coupling": True,
@@ -339,6 +340,26 @@ class AdvancedSettings(SettingsBase):
339
340
  depending on drawing size, number of modes, and/or maximum sweep
340
341
  frequency.
341
342
 
343
+ .. deprecated:: 0.54.0
344
+ Use :func:`automatic_mesh` instead.
345
+
346
+ Returns
347
+ -------
348
+ bool
349
+ ``True`` if automatic mesh is used, ``False`` otherwise.
350
+ """
351
+ warnings.warn(
352
+ "`automatic_mesh` is deprecated." "Use `mesh_automatic` instead.",
353
+ DeprecationWarning,
354
+ )
355
+ return self.sim_setup_info.simulation_settings.AdvancedSettings.MeshAutoMatic
356
+
357
+ @property
358
+ def mesh_automatic(self):
359
+ """Whether to automatically pick a suitable mesh refinement frequency,
360
+ depending on drawing size, number of modes, and/or maximum sweep
361
+ frequency.
362
+
342
363
  Returns
343
364
  -------
344
365
  bool
@@ -492,6 +513,10 @@ class AdvancedSettings(SettingsBase):
492
513
 
493
514
  @automatic_mesh.setter
494
515
  def automatic_mesh(self, value):
516
+ self.mesh_automatic = value
517
+
518
+ @mesh_automatic.setter
519
+ def mesh_automatic(self, value):
495
520
  edb_setup_info = self.sim_setup_info
496
521
 
497
522
  edb_setup_info.simulation_settings.AdvancedSettings.MeshAutoMatic = value