pyedb 0.27.0__py3-none-any.whl → 0.28.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.

pyedb/__init__.py CHANGED
@@ -44,7 +44,7 @@ deprecation_warning()
44
44
  #
45
45
 
46
46
  pyedb_path = os.path.dirname(__file__)
47
- __version__ = "0.27.0"
47
+ __version__ = "0.28.0"
48
48
  version = __version__
49
49
 
50
50
  #
@@ -53,7 +53,7 @@ class CfgData(object):
53
53
 
54
54
  self.components = CfgComponents(self._pedb, components_data=kwargs.get("components", []))
55
55
 
56
- self.padstacks = CfgPadstacks(self, kwargs.get("padstacks", None))
56
+ self.padstacks = CfgPadstacks(self._pedb, kwargs.get("padstacks", None))
57
57
 
58
58
  self.pin_groups = CfgPinGroups(self._pedb, pingroup_data=kwargs.get("pin_groups", []))
59
59
 
@@ -65,7 +65,7 @@ class CfgCutout(CfgBase):
65
65
 
66
66
  self.reference_list = []
67
67
  self.signal_list = net_names
68
- return self.export_properties()
68
+ return self.export_properties()
69
69
 
70
70
  def export_properties(self):
71
71
  return {
@@ -84,7 +84,7 @@ class CfgOperations(CfgBase):
84
84
  """Imports operation information from JSON."""
85
85
  if self.op_cutout:
86
86
  polygon_points = self._pedb.cutout(**self.op_cutout.get_attributes())
87
- if not "pyedb_cutout" in self._pedb.stackup.all_layers:
87
+ if "pyedb_cutout" not in self._pedb.stackup.all_layers:
88
88
  self._pedb.stackup.add_document_layer(name="pyedb_cutout")
89
89
  self._pedb.modeler.create_polygon(polygon_points, layer_name="pyedb_cutout", net_name="pyedb_cutout")
90
90
 
@@ -92,4 +92,6 @@ class CfgOperations(CfgBase):
92
92
 
93
93
  def get_data_from_db(self):
94
94
  self.op_cutout = CfgCutout(self._pedb)
95
- return {"cutout": self.op_cutout.get_data_from_db()}
95
+ data_from_db = self.op_cutout.get_data_from_db()
96
+ if data_from_db:
97
+ return {"cutout": data_from_db}
@@ -23,62 +23,69 @@
23
23
 
24
24
  from enum import Enum
25
25
 
26
+ from pyedb.configuration.cfg_common import CfgBase
27
+
26
28
 
27
29
  class CfgPadstacks:
28
30
  """Padstack data class."""
29
31
 
30
- def __init__(self, pdata, padstack_dict=None):
31
- self._pedb = pdata._pedb
32
+ def __init__(self, pedb, padstack_dict=None):
33
+ self._pedb = pedb
32
34
  self.definitions = []
33
35
  self.instances = []
34
- self._padstack_dict = padstack_dict
35
- if self._padstack_dict:
36
- if self._padstack_dict.get("definitions", ""):
37
- self._definitions_dict = self._padstack_dict.get("definitions", "")
38
- self.definitions = [Definition(pdata, definition) for definition in self._definitions_dict]
39
- if self._padstack_dict.get("instances", None):
40
- self._instances_dict = self._padstack_dict.get("instances", "")
41
- self.instances = [Instance(pdata, inst) for inst in self._instances_dict]
36
+ if padstack_dict:
37
+ for pdef in padstack_dict.get("definitions", []):
38
+ self.definitions.append(Definition(**pdef))
39
+ for inst in padstack_dict.get("instances", []):
40
+ self.instances.append(Instance(self._pedb, inst))
42
41
 
43
42
  def apply(self):
44
43
  """Apply padstack definition and instances on layout."""
45
- for definition in self.definitions:
46
- definition.apply()
44
+ padstack_defs_layout = self._pedb.padstacks.definitions
45
+ for pdef in self.definitions:
46
+ pdef_layout = padstack_defs_layout[pdef.name]
47
+ pdef_layout.set_properties(**pdef.get_attributes())
47
48
  for instance in self.instances:
48
49
  instance.apply()
49
50
 
51
+ def get_data_from_db(self):
52
+ self.definitions = []
53
+ for pdef_name, pdef in self._pedb.padstacks.definitions.items():
54
+ self.definitions.append(
55
+ Definition(
56
+ name=pdef_name,
57
+ hole_plating_thickness=pdef.hole_plating_thickness,
58
+ hole_material=pdef.material,
59
+ hole_range=pdef.hole_range,
60
+ pad_parameters=pdef.pad_parameters,
61
+ hole_parameters=pdef.hole_parameters,
62
+ )
63
+ )
64
+ data = {}
65
+ definitions = []
66
+ for i in self.definitions:
67
+ definitions.append(i.get_attributes())
68
+ data["definitions"] = definitions
69
+ return data
70
+
50
71
 
51
- class Definition:
72
+ class Definition(CfgBase):
52
73
  """Padstack definition data class."""
53
74
 
54
- def __init__(self, pdata, definition_dict):
55
- self._pedb = pdata._pedb
56
- self._definition_dict = definition_dict
57
- self.name = self._definition_dict.get("name", None)
58
- self.hole_diameter = self._definition_dict.get("hole_diameter", None)
59
- self.hole_plating_thickness = self._definition_dict.get("hole_plating_thickness", None)
60
- self.hole_material = self._definition_dict.get("hole_material", None)
61
- self.hole_range = self._definition_dict.get("hole_range", None)
62
-
63
- def apply(self):
64
- """Apply padstack definition on layout."""
65
- padstack_defs = self._pedb.padstacks.definitions
66
- pdef = padstack_defs[self.name]
67
- if self.hole_diameter:
68
- pdef.hole_diameter = self.hole_diameter
69
- if self.hole_plating_thickness:
70
- pdef.hole_plating_thickness = self.hole_plating_thickness
71
- if self.hole_material:
72
- pdef.material = self.hole_material
73
- if self.hole_range:
74
- pdef.hole_range = self.hole_range
75
+ def __init__(self, **kwargs):
76
+ self.name = kwargs.get("name", None)
77
+ self.hole_plating_thickness = kwargs.get("hole_plating_thickness", None)
78
+ self.material = kwargs.get("hole_material", None)
79
+ self.hole_range = kwargs.get("hole_range", None)
80
+ self.pad_parameters = kwargs.get("pad_parameters", None)
81
+ self.hole_parameters = kwargs.get("hole_parameters", None)
75
82
 
76
83
 
77
84
  class Instance:
78
85
  """Instance data class."""
79
86
 
80
- def __init__(self, pdata, instances_dict):
81
- self._pedb = pdata._pedb
87
+ def __init__(self, pedb, instances_dict):
88
+ self._pedb = pedb
82
89
  self._instances_dict = instances_dict
83
90
  self.name = self._instances_dict.get("name", "")
84
91
  self.backdrill_top = None
@@ -36,12 +36,14 @@ class CfgPinGroups:
36
36
 
37
37
  def get_data_from_db(self):
38
38
  self.pin_groups = []
39
- for name, pg in self._pedb.siwave.pin_groups.items():
40
- pins = [p.aedt_name for p in pg.pins.values()]
39
+ layout_pin_groups = self._pedb.siwave.pin_groups
40
+ for pg_name, pg_obj in layout_pin_groups.items():
41
+ pins = list(pg_obj.pins.keys())
42
+ refdes = list(pg_obj.pins.values())[0].component.name
41
43
  cfg_pg = CfgPinGroup(
42
44
  self._pedb,
43
- name=name,
44
- reference_designator=None,
45
+ name=pg_name,
46
+ reference_designator=refdes,
45
47
  pins=pins,
46
48
  )
47
49
  self.pin_groups.append(cfg_pg)
@@ -65,10 +67,7 @@ class CfgPinGroup(CfgBase):
65
67
  def create(self):
66
68
  """Apply pin group on layout."""
67
69
  if self.pins:
68
- if self.reference_designator is None:
69
- self._pedb.modeler.create_pin_group(self.name, pins_by_aedt_name=self.pins)
70
- else:
71
- self._pedb.siwave.create_pin_group(self.reference_designator, list(self.pins), self.name)
70
+ self._pedb.siwave.create_pin_group(self.reference_designator, list(self.pins), self.name)
72
71
  elif self.net:
73
72
  if self.reference_designator in self._pedb.components.instances:
74
73
  comp = self._pedb.components.instances[self.reference_designator]
@@ -74,7 +74,7 @@ class Configuration:
74
74
  elif config_file.endswith(".toml"):
75
75
  data = toml.load(f)
76
76
  else: # pragma: no cover
77
- return False
77
+ raise RuntimeError(f"File {config_file} does not exist.")
78
78
 
79
79
  if not append: # pragma: no cover
80
80
  self.data = {}
@@ -103,7 +103,7 @@ class Configuration:
103
103
  self._pedb.open_edb()
104
104
  return self.cfg_data
105
105
 
106
- def run(self):
106
+ def run(self, **kwargs):
107
107
  """Apply configuration settings to the current design"""
108
108
 
109
109
  # Configure boundary settings
@@ -134,7 +134,16 @@ class Configuration:
134
134
  self.cfg_data.setups.apply()
135
135
 
136
136
  # Configure stackup
137
- self.cfg_data.stackup.apply()
137
+ if kwargs.get("fix_padstack_def"):
138
+ pedb_defs = self._pedb.padstacks.definitions
139
+ temp = {}
140
+ for name, pdef in pedb_defs.items():
141
+ temp[name] = pdef.get_properties()
142
+ self.cfg_data.stackup.apply()
143
+ for name, pdef_p in temp.items():
144
+ pedb_defs[name].set_properties(**pdef_p)
145
+ else:
146
+ self.cfg_data.stackup.apply()
138
147
 
139
148
  # Configure S-parameter
140
149
  for s_parameter_model in self.cfg_data.s_parameters:
@@ -282,6 +291,8 @@ class Configuration:
282
291
  data["pin_groups"] = self.cfg_data.pin_groups.get_data_from_db()
283
292
  if kwargs.get("operations", False):
284
293
  data["operations"] = self.cfg_data.operations.get_data_from_db()
294
+ if kwargs.get("padstacks", False):
295
+ data["padstacks"] = self.cfg_data.padstacks.get_data_from_db()
285
296
 
286
297
  return data
287
298
 
@@ -27,7 +27,7 @@ This module is used to create and edit design and project variables in the 3D to
27
27
 
28
28
  Examples
29
29
  --------
30
- >>> from pyaedt import Hfss
30
+ >>> from ansys.aedt.core import Hfss
31
31
  >>> hfss = Hfss()
32
32
  >>> hfss["$d"] = "5mm"
33
33
  >>> hfss["d"] = "5mm"
@@ -415,8 +415,8 @@ class VariableManager(object):
415
415
  Examples
416
416
  --------
417
417
 
418
- >>> from pyaedt.maxwell import Maxwell3d
419
- >>> from pyaedt.desktop import Desktop
418
+ >>> from ansys.aedt.core.maxwell import Maxwell3d
419
+ >>> from ansys.aedt.core.desktop import Desktop
420
420
  >>> d = Desktop()
421
421
  >>> aedtapp = Maxwell3d()
422
422
 
@@ -1765,40 +1765,42 @@ class Variable(object):
1765
1765
  def __mul__(self, other): # pragma: no cover
1766
1766
  """Multiply the variable with a number or another variable and return a new object.
1767
1767
 
1768
- Parameters
1769
- ----------
1770
- other : numbers.Number or variable
1771
- Object to be multiplied.
1772
-
1773
- Returns
1774
- -------
1775
- type
1776
- Variable.
1777
-
1778
- Examples
1779
- --------
1780
- >>> from pyedb.dotnet.application.Variables import Variable
1781
-
1782
- Multiply ``'Length1'`` by unitless ``'None'``` to obtain ``'Length'``.
1783
- A numerical value is also considered to be unitless.
1784
-
1785
- import pyaedt.generic.constants >>> v1 = Variable("10mm")
1786
- >>> v2 = Variable(3)
1787
- >>> result_1 = v1 * v2
1788
- >>> result_2 = v1 * 3
1789
- >>> assert result_1.numeric_value == 30.0
1790
- >>> assert result_1.unit_system == "Length"
1791
- >>> assert result_2.numeric_value == result_1.numeric_value
1792
- >>> assert result_2.unit_system == "Length"
1793
-
1794
- Multiply voltage times current to obtain power.
1795
-
1796
- import pyaedt.generic.constants >>> v3 = Variable("3mA")
1797
- >>> v4 = Variable("40V")
1798
- >>> result_3 = v3 * v4
1799
- >>> assert result_3.numeric_value == 0.12
1800
- >>> assert result_3.units == "W"
1801
- >>> assert result_3.unit_system == "Power"
1768
+ Parameters
1769
+ ----------
1770
+ other : numbers.Number or variable
1771
+ Object to be multiplied.
1772
+
1773
+ Returns
1774
+ -------
1775
+ type
1776
+ Variable.
1777
+
1778
+ Examples
1779
+ --------
1780
+ >>> from pyedb.dotnet.application.Variables import Variable
1781
+
1782
+ Multiply ``'Length1'`` by unitless ``'None'``` to obtain ``'Length'``.
1783
+ A numerical value is also considered to be unitless.
1784
+
1785
+ >>> import ansys.aedt.core.generic.constants
1786
+ >>> v1 = Variable("10mm")
1787
+ >>> v2 = Variable(3)
1788
+ >>> result_1 = v1 * v2
1789
+ >>> result_2 = v1 * 3
1790
+ >>> assert result_1.numeric_value == 30.0
1791
+ >>> assert result_1.unit_system == "Length"
1792
+ >>> assert result_2.numeric_value == result_1.numeric_value
1793
+ >>> assert result_2.unit_system == "Length"
1794
+
1795
+ Multiply voltage times current to obtain power.
1796
+
1797
+ >>> import ansys.aedt.core.generic.constants
1798
+ >>> v3 = Variable("3mA")
1799
+ >>> v4 = Variable("40V")
1800
+ >>> result_3 = v3 * v4
1801
+ >>> assert result_3.numeric_value == 0.12
1802
+ >>> assert result_3.units == "W"
1803
+ >>> assert result_3.unit_system == "Power"
1802
1804
 
1803
1805
  """
1804
1806
  assert is_number(other) or isinstance(other, Variable), "Multiplier must be a scalar quantity or a variable."
@@ -1836,7 +1838,7 @@ class Variable(object):
1836
1838
  Examples
1837
1839
  --------
1838
1840
  >>> from pyedb.dotnet.application.Variables import Variable
1839
- >>> import pyaedt.generic.constants
1841
+ >>> import ansys.aedt.core.generic.constants
1840
1842
  >>> v1 = Variable("3mA")
1841
1843
  >>> v2 = Variable("10A")
1842
1844
  >>> result = v1 + v2
@@ -1876,7 +1878,7 @@ class Variable(object):
1876
1878
  Examples
1877
1879
  --------
1878
1880
 
1879
- >>> import pyaedt.generic.constants
1881
+ >>> import ansys.aedt.core.generic.constants
1880
1882
  >>> from pyedb.dotnet.application.Variables import Variable
1881
1883
  >>> v3 = Variable("3mA")
1882
1884
  >>> v4 = Variable("10A")
@@ -1922,7 +1924,7 @@ class Variable(object):
1922
1924
  resolve the new units to ``"A"``.
1923
1925
 
1924
1926
  >>> from pyedb.dotnet.application.Variables import Variable
1925
- >>> import pyaedt.generic.constants
1927
+ >>> import ansys.aedt.core.generic.constants
1926
1928
  >>> v1 = Variable("10W")
1927
1929
  >>> v2 = Variable("40V")
1928
1930
  >>> result = v1 / v2
@@ -1964,7 +1966,7 @@ class Variable(object):
1964
1966
  Divide a number by a variable with units ``"s"`` and automatically determine that
1965
1967
  the result is in ``"Hz"``.
1966
1968
 
1967
- >>> import pyaedt.generic.constants
1969
+ >>> import ansys.aedt.core.generic.constants
1968
1970
  >>> from pyedb.dotnet.application.Variables import Variable
1969
1971
  >>> v = Variable("1s")
1970
1972
  >>> result = 3.0 / v
@@ -323,7 +323,10 @@ class Layout(ObjBase):
323
323
 
324
324
  """
325
325
  obj = self._pedb._edb.Cell.Net.FindByName(self._edb_object, value)
326
- return EDBNetsData(obj, self._pedb) if obj is not None else None
326
+ if obj.IsNull():
327
+ raise ValueError(f"Net {value} doesn't exist")
328
+ else:
329
+ return EDBNetsData(obj, self._pedb)
327
330
 
328
331
  def find_component_by_name(self, value: str):
329
332
  """Find a component object by name. Component name is the reference designator in layout.
@@ -47,10 +47,10 @@ class PinGroupTerminal(Terminal):
47
47
  -------
48
48
  :class:`pyedb.dotnet.edb_core.edb_data.terminals.PinGroupTerminal`
49
49
  """
50
- net_obj = self._pedb.edb_api.cell.net.find_by_name(self._pedb.active_layout, net_name)
50
+ net_obj = self._pedb.layout.find_net_by_name(net_name)
51
51
  term = self._pedb.edb_api.cell.terminal.PinGroupTerminal.Create(
52
52
  self._pedb.active_layout,
53
- net_obj.api_object,
53
+ net_obj._edb_object,
54
54
  name,
55
55
  self._pedb.siwave.pin_groups[pin_group_name]._edb_object,
56
56
  is_ref,
@@ -60,7 +60,7 @@ class PinGroupTerminal(Terminal):
60
60
  msg = f"Failed to create terminal. "
61
61
  if name in self._pedb.terminals:
62
62
  msg += f"Terminal {name} already exists."
63
- raise Exception(msg)
63
+ raise ValueError(msg)
64
64
  else:
65
65
  return term
66
66
 
@@ -29,7 +29,12 @@ from pyedb.dotnet.clr_module import String
29
29
  from pyedb.dotnet.edb_core.cell.primitive.primitive import Primitive
30
30
  from pyedb.dotnet.edb_core.dotnet.database import PolygonDataDotNet
31
31
  from pyedb.dotnet.edb_core.edb_data.edbvalue import EdbValue
32
- from pyedb.dotnet.edb_core.general import PadGeometryTpe, convert_py_list_to_net_list
32
+ from pyedb.dotnet.edb_core.general import (
33
+ PadGeometryTpe,
34
+ convert_py_list_to_net_list,
35
+ pascal_to_snake,
36
+ snake_to_pascal,
37
+ )
33
38
  from pyedb.generic.general_methods import generate_unique_name
34
39
  from pyedb.modeler.geometry_operators import GeometryOperators
35
40
 
@@ -406,19 +411,231 @@ class EDBPadstack(object):
406
411
  >>> edb_padstack = edb.padstacks.definitions["MyPad"]
407
412
  """
408
413
 
414
+ PAD_SHAPE_PARAMETERS = {
415
+ "circle": ["diameter"],
416
+ "square": ["size"],
417
+ "rectangle": ["x_size", "y_size"],
418
+ "oval": ["x_size", "y_size", "corner_radius"],
419
+ "bullet": ["x_size", "y_size", "corner_radius"],
420
+ "round45": ["inner", "channel_width", "isolation_gap"],
421
+ "round90": ["inner", "channel_width", "isolation_gap"],
422
+ "no_geometry": [],
423
+ }
424
+
409
425
  def __init__(self, edb_padstack, ppadstack):
426
+ self._edb_object = edb_padstack
410
427
  self.edb_padstack = edb_padstack
411
428
  self._ppadstack = ppadstack
412
- self.pad_by_layer = {}
413
- self.antipad_by_layer = {}
414
- self.thermalpad_by_layer = {}
415
429
  self._bounding_box = []
416
430
  self._hole_params = None
431
+
432
+ @property
433
+ def pad_by_layer(self):
434
+ """Regular pad property."""
435
+ temp = {}
417
436
  for layer in self.via_layers:
418
- self.pad_by_layer[layer] = EDBPadProperties(edb_padstack, layer, 0, self)
419
- self.antipad_by_layer[layer] = EDBPadProperties(edb_padstack, layer, 1, self)
420
- self.thermalpad_by_layer[layer] = EDBPadProperties(edb_padstack, layer, 2, self)
421
- pass
437
+ temp[layer] = EDBPadProperties(self._edb_object, layer, 0, self)
438
+ return temp
439
+
440
+ @property
441
+ def antipad_by_layer(self):
442
+ """Anti pad property."""
443
+ temp = {}
444
+ for layer in self.via_layers:
445
+ temp[layer] = EDBPadProperties(self._edb_object, layer, 1, self)
446
+ return temp
447
+
448
+ @property
449
+ def thermalpad_by_layer(self):
450
+ """Thermal pad property."""
451
+ temp = {}
452
+ for layer in self.via_layers:
453
+ temp[layer] = EDBPadProperties(self._edb_object, layer, 2, self)
454
+ return temp
455
+
456
+ @property
457
+ def _padstack_def_data(self):
458
+ """Get padstack definition data.
459
+
460
+ Returns
461
+ -------
462
+
463
+ """
464
+ pstack_data = self._edb_object.GetData()
465
+ return self._edb.definition.PadstackDefData(pstack_data)
466
+
467
+ @_padstack_def_data.setter
468
+ def _padstack_def_data(self, value):
469
+ self._edb_object.SetData(value)
470
+
471
+ @property
472
+ def pad_parameters(self) -> dict:
473
+ """Pad parameters.
474
+
475
+ Returns
476
+ -------
477
+ dict
478
+ params = {
479
+ 'regular_pad': [
480
+ {'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0.1mm', 'offset_y': '0', 'rotation': '0',
481
+ 'diameter': '0.5mm'}
482
+ ],
483
+ 'anti_pad': [
484
+ {'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
485
+ 'diameter': '1mm'}
486
+ ],
487
+ 'thermal_pad': [
488
+ {'layer_name': '1_Top', 'shape': 'round90', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
489
+ 'inner': '1mm', 'channel_width': '0.2mm', 'isolation_gap': '0.3mm'},
490
+ ],
491
+ 'hole': [
492
+ {'layer_name': '1_Top', 'shape': 'circle', 'offset_x': '0', 'offset_y': '0', 'rotation': '0',
493
+ 'diameter': '0.1499997mm'},
494
+ ]
495
+ }
496
+ """
497
+ pdef_data = self._padstack_def_data
498
+ pad_type_list = [
499
+ self._ppadstack._pedb._edb.Definition.PadType.RegularPad,
500
+ self._ppadstack._pedb._edb.Definition.PadType.AntiPad,
501
+ self._ppadstack._pedb._edb.Definition.PadType.ThermalPad,
502
+ self._ppadstack._pedb._edb.Definition.PadType.Hole,
503
+ ]
504
+ data = {}
505
+ for pad_type in pad_type_list:
506
+ pad_type_name = pascal_to_snake(pad_type.ToString())
507
+ temp_list = []
508
+ for lyr_name in list(pdef_data.GetLayerNames()):
509
+ result = pdef_data.GetPadParametersValue(lyr_name, pad_type)
510
+ _, pad_shape, params, offset_x, offset_y, rotation = result
511
+ pad_shape = pascal_to_snake(pad_shape.ToString())
512
+
513
+ pad_params = {}
514
+ pad_params["layer_name"] = lyr_name
515
+ pad_params["shape"] = pad_shape
516
+ pad_params["offset_x"] = offset_x.ToString()
517
+ pad_params["offset_y"] = offset_y.ToString()
518
+ pad_params["rotation"] = rotation.ToString()
519
+
520
+ for idx, i in enumerate(self.PAD_SHAPE_PARAMETERS[pad_shape]):
521
+ pad_params[i] = params[idx].ToString()
522
+ temp_list.append(pad_params)
523
+ data[pad_type_name] = temp_list
524
+ return data
525
+
526
+ @pad_parameters.setter
527
+ def pad_parameters(self, params: dict):
528
+ original_params = self.pad_parameters
529
+ pdef_data = self._padstack_def_data
530
+
531
+ pad_type_list = [
532
+ self._ppadstack._pedb._edb.Definition.PadType.RegularPad,
533
+ self._ppadstack._pedb._edb.Definition.PadType.AntiPad,
534
+ self._ppadstack._pedb._edb.Definition.PadType.ThermalPad,
535
+ self._ppadstack._pedb._edb.Definition.PadType.Hole,
536
+ ]
537
+ for pad_type in pad_type_list:
538
+ pad_type_name = pascal_to_snake(pad_type.ToString())
539
+ rpp = params.get(pad_type_name, [])
540
+ for idx, layer_data in enumerate(rpp):
541
+ # Get geometry type from kwargs
542
+ p = layer_data.get("shape")
543
+ temp_param = []
544
+
545
+ # Handle Circle geometry type
546
+ if p == pascal_to_snake(self._ppadstack._pedb._edb.Definition.PadGeometryType.Circle.ToString()):
547
+ temp_param.append(layer_data["diameter"])
548
+ pad_shape = self._ppadstack._pedb._edb.Definition.PadGeometryType.Circle
549
+
550
+ # Handle Square geometry type
551
+ elif p == pascal_to_snake(self._ppadstack._pedb._edb.Definition.PadGeometryType.Square.ToString()):
552
+ temp_param.append(layer_data["size"])
553
+ pad_shape = self._ppadstack._pedb._edb.Definition.PadGeometryType.Square
554
+
555
+ elif p == pascal_to_snake(self._ppadstack._pedb._edb.Definition.PadGeometryType.Rectangle.ToString()):
556
+ temp_param.append(layer_data["x_size"])
557
+ temp_param.append(layer_data["y_size"])
558
+ pad_shape = self._ppadstack._pedb._edb.Definition.PadGeometryType.Rectangle
559
+
560
+ # Handle Oval geometry type
561
+ elif p == pascal_to_snake(self._ppadstack._pedb._edb.Definition.PadGeometryType.Oval.ToString()):
562
+ temp_param.append(layer_data["x_size"])
563
+ temp_param.append(layer_data["y_size"])
564
+ temp_param.append(layer_data["corner_radius"])
565
+ pad_shape = self._ppadstack._pedb._edb.Definition.PadGeometryType.Oval
566
+
567
+ # Handle Bullet geometry type
568
+ elif p == pascal_to_snake(self._ppadstack._pedb._edb.Definition.PadGeometryType.Bullet.ToString()):
569
+ temp_param.append(layer_data["x_size"])
570
+ temp_param.append(layer_data["y_size"])
571
+ temp_param.append(layer_data["corner_radius"])
572
+ pad_shape = self._ppadstack._pedb._edb.Definition.PadGeometryType.Bullet
573
+
574
+ # Handle Round45 geometry type
575
+ elif p == pascal_to_snake(self._ppadstack._pedb._edb.Definition.PadGeometryType.Round45.ToString()):
576
+ temp_param.append(layer_data["inner"])
577
+ temp_param.append(layer_data["channel_width"])
578
+ temp_param.append(layer_data["isolation_gap"])
579
+ pad_shape = self._ppadstack._pedb._edb.Definition.PadGeometryType.Round45
580
+
581
+ # Handle Round90 geometry type
582
+ elif p == pascal_to_snake(self._ppadstack._pedb._edb.Definition.PadGeometryType.Round90.ToString()):
583
+ temp_param.append(layer_data["inner"])
584
+ temp_param.append(layer_data["channel_width"])
585
+ temp_param.append(layer_data["isolation_gap"])
586
+ pad_shape = self._ppadstack._pedb._edb.Definition.PadGeometryType.Round90
587
+ elif p == pascal_to_snake(self._ppadstack._pedb._edb.Definition.PadGeometryType.NoGeometry.ToString()):
588
+ continue
589
+
590
+ # Set pad parameters for the current layer
591
+ default = original_params[pad_type_name]
592
+ pdef_data.SetPadParameters(
593
+ layer_data["layer_name"],
594
+ pad_type,
595
+ pad_shape,
596
+ convert_py_list_to_net_list([self._ppadstack._pedb.edb_value(i) for i in temp_param]),
597
+ self._ppadstack._pedb.edb_value(layer_data.get("offset_x", default[idx].get("offset_x", 0))),
598
+ self._ppadstack._pedb.edb_value(layer_data.get("offset_y", default[idx].get("offset_y", 0))),
599
+ self._ppadstack._pedb.edb_value(layer_data.get("rotation", default[idx].get("rotation", 0))),
600
+ )
601
+ self._padstack_def_data = pdef_data
602
+
603
+ @property
604
+ def hole_parameters(self):
605
+ pdef_data = self._padstack_def_data
606
+ _, hole_shape, params, offset_x, offset_y, rotation = pdef_data.GetHoleParametersValue()
607
+ hole_shape = pascal_to_snake(hole_shape.ToString())
608
+
609
+ hole_params = {}
610
+ hole_params["shape"] = hole_shape
611
+ for idx, i in enumerate(self.PAD_SHAPE_PARAMETERS[hole_shape]):
612
+ hole_params[i] = params[idx].ToString()
613
+ hole_params["offset_x"] = offset_x.ToString()
614
+ hole_params["offset_y"] = offset_y.ToString()
615
+ hole_params["rotation"] = rotation.ToString()
616
+ return hole_params
617
+
618
+ @hole_parameters.setter
619
+ def hole_parameters(self, params: dict):
620
+ original_params = self.hole_parameters
621
+ pdef_data = self._padstack_def_data
622
+
623
+ temp_param = []
624
+ shape = params["shape"]
625
+ if shape == "no_geometry":
626
+ return # .net api doesn't tell how to set no_geometry shape.
627
+ for idx, i in enumerate(self.PAD_SHAPE_PARAMETERS[shape]):
628
+ temp_param.append(params[i])
629
+ pedb_shape = getattr(self._ppadstack._pedb._edb.Definition.PadGeometryType, snake_to_pascal(shape))
630
+
631
+ pdef_data.SetHoleParameters(
632
+ pedb_shape,
633
+ convert_py_list_to_net_list([self._ppadstack._pedb.edb_value(i) for i in temp_param]),
634
+ self._ppadstack._pedb.edb_value(params.get("offset_x", original_params.get("offset_x", 0))),
635
+ self._ppadstack._pedb.edb_value(params.get("offset_y", original_params.get("offset_y", 0))),
636
+ self._ppadstack._pedb.edb_value(params.get("rotation", original_params.get("rotation", 0))),
637
+ )
638
+ self._padstack_def_data = pdef_data
422
639
 
423
640
  @property
424
641
  def instances(self):
@@ -455,7 +672,7 @@ class EDBPadstack(object):
455
672
  list
456
673
  List of layers.
457
674
  """
458
- return self.edb_padstack.GetData().GetLayerNames()
675
+ return self._padstack_def_data.GetLayerNames()
459
676
 
460
677
  @property
461
678
  def via_start_layer(self):
@@ -488,7 +705,7 @@ class EDBPadstack(object):
488
705
  return self._hole_params
489
706
 
490
707
  @property
491
- def hole_parameters(self):
708
+ def _hole_parameters(self):
492
709
  """Hole parameters.
493
710
 
494
711
  Returns
@@ -496,8 +713,7 @@ class EDBPadstack(object):
496
713
  list
497
714
  List of the hole parameters.
498
715
  """
499
- self._hole_parameters = self.hole_params[2]
500
- return self._hole_parameters
716
+ return self.hole_params[2]
501
717
 
502
718
  @property
503
719
  def hole_diameter(self):
@@ -540,7 +756,7 @@ class EDBPadstack(object):
540
756
  if not hole_type:
541
757
  hole_type = self.hole_type
542
758
  if not params:
543
- params = self.hole_parameters
759
+ params = self._hole_parameters
544
760
  if isinstance(params, list):
545
761
  params = convert_py_list_to_net_list(params)
546
762
  if not offsetx:
@@ -709,14 +925,13 @@ class EDBPadstack(object):
709
925
  str
710
926
  Material of the hole.
711
927
  """
712
- return self.edb_padstack.GetData().GetMaterial()
928
+ return self._padstack_def_data.GetMaterial()
713
929
 
714
930
  @material.setter
715
931
  def material(self, materialname):
716
- originalPadstackDefinitionData = self.edb_padstack.GetData()
717
- newPadstackDefinitionData = self._edb.definition.PadstackDefData(originalPadstackDefinitionData)
718
- newPadstackDefinitionData.SetMaterial(materialname)
719
- self.edb_padstack.SetData(newPadstackDefinitionData)
932
+ pdef_data = self._padstack_def_data
933
+ pdef_data.SetMaterial(materialname)
934
+ self._padstack_def_data = pdef_data
720
935
 
721
936
  @property
722
937
  def padstack_instances(self):
@@ -736,36 +951,15 @@ class EDBPadstack(object):
736
951
  -------
737
952
  str
738
953
  Possible returned values are ``"through"``, ``"begin_on_upper_pad"``,
739
- ``"end_on_lower_pad"``, ``"upper_pad_to_lower_pad"``, and ``"undefined"``.
954
+ ``"end_on_lower_pad"``, ``"upper_pad_to_lower_pad"``, and ``"unknown_range"``.
740
955
  """
741
- cloned_padstackdef_data = self._edb.definition.PadstackDefData(self.edb_padstack.GetData())
742
- hole_ange_type = int(cloned_padstackdef_data.GetHoleRange())
743
- if hole_ange_type == 0: # pragma no cover
744
- return "through"
745
- elif hole_ange_type == 1: # pragma no cover
746
- return "begin_on_upper_pad"
747
- elif hole_ange_type == 2: # pragma no cover
748
- return "end_on_lower_pad"
749
- elif hole_ange_type == 3: # pragma no cover
750
- return "upper_pad_to_lower_pad"
751
- else: # pragma no cover
752
- return "undefined"
956
+ return pascal_to_snake(self._padstack_def_data.GetHoleRange().ToString())
753
957
 
754
958
  @hole_range.setter
755
959
  def hole_range(self, value):
756
- if isinstance(value, str): # pragma no cover
757
- cloned_padstackdef_data = self._edb.definition.PadstackDefData(self.edb_padstack.GetData())
758
- if value == "through": # pragma no cover
759
- cloned_padstackdef_data.SetHoleRange(self._edb.definition.PadstackHoleRange.Through)
760
- elif value == "begin_on_upper_pad": # pragma no cover
761
- cloned_padstackdef_data.SetHoleRange(self._edb.definition.PadstackHoleRange.BeginOnUpperPad)
762
- elif value == "end_on_lower_pad": # pragma no cover
763
- cloned_padstackdef_data.SetHoleRange(self._edb.definition.PadstackHoleRange.EndOnLowerPad)
764
- elif value == "upper_pad_to_lower_pad": # pragma no cover
765
- cloned_padstackdef_data.SetHoleRange(self._edb.definition.PadstackHoleRange.UpperPadToLowerPad)
766
- else: # pragma no cover
767
- return
768
- self.edb_padstack.SetData(cloned_padstackdef_data)
960
+ pdef_data = self._padstack_def_data
961
+ pdef_data.SetHoleRange(getattr(self._edb.definition.PadstackHoleRange, snake_to_pascal(value)))
962
+ self._padstack_def_data = pdef_data
769
963
 
770
964
  def convert_to_3d_microvias(self, convert_only_signal_vias=True, hole_wall_angle=15, delete_padstack_def=True):
771
965
  """Convert actual padstack instance to microvias 3D Objects with a given aspect ratio.
@@ -984,7 +1178,7 @@ class EDBPadstack(object):
984
1178
  )
985
1179
  new_padstack_definition_data.SetHoleParameters(
986
1180
  self.hole_type,
987
- self.hole_parameters,
1181
+ self._hole_parameters,
988
1182
  self._get_edb_value(self.hole_offset_x),
989
1183
  self._get_edb_value(self.hole_offset_y),
990
1184
  self._get_edb_value(self.hole_rotation),
@@ -1128,6 +1322,18 @@ class EDBPadstack(object):
1128
1322
  self.edb_padstack.SetData(new_padstack_data)
1129
1323
  return True
1130
1324
 
1325
+ def set_properties(self, **kwargs):
1326
+ for k in ["hole_plating_thickness", "material", "hole_range", "pad_parameters", "hole_parameters"]:
1327
+ value = kwargs.get(k, False)
1328
+ if value:
1329
+ setattr(self, k, value)
1330
+
1331
+ def get_properties(self):
1332
+ kwargs = {}
1333
+ for k in ["hole_plating_thickness", "material", "hole_range", "pad_parameters", "hole_parameters"]:
1334
+ kwargs[k] = getattr(self, k)
1335
+ return kwargs
1336
+
1131
1337
 
1132
1338
  class EDBPadstackInstance(Primitive):
1133
1339
  """Manages EDB functionalities for a padstack.
@@ -158,7 +158,7 @@ class EdbPolygon(Primitive):
158
158
 
159
159
  Examples
160
160
  --------
161
- >>> edbapp = pyaedt.Edb("myproject.aedb")
161
+ >>> edbapp = ansys.aedt.core.Edb("myproject.aedb")
162
162
  >>> top_layer_polygon = [poly for poly in edbapp.modeler.polygons if poly.layer_name == "Top Layer"]
163
163
  >>> for polygon in top_layer_polygon:
164
164
  >>> polygon.move(vector=["2mm", "100um"])
@@ -191,7 +191,7 @@ class EdbPolygon(Primitive):
191
191
 
192
192
  Examples
193
193
  --------
194
- >>> edbapp = pyaedt.Edb("myproject.aedb")
194
+ >>> edbapp = ansys.aedt.core.Edb("myproject.aedb")
195
195
  >>> top_layer_polygon = [poly for poly in edbapp.modeler.polygons if poly.layer_name == "Top Layer"]
196
196
  >>> for polygon in top_layer_polygon:
197
197
  >>> polygon.rotate(angle=45)
@@ -28,6 +28,7 @@ This module contains EDB general methods and related methods.
28
28
  from __future__ import absolute_import # noreorder
29
29
 
30
30
  import logging
31
+ import re
31
32
 
32
33
  from pyedb.dotnet.clr_module import Dictionary, List, Tuple
33
34
 
@@ -140,6 +141,16 @@ def convert_net_list_to_py_list(netlist):
140
141
  return pylist
141
142
 
142
143
 
144
+ def pascal_to_snake(s):
145
+ # Convert PascalCase to snake_case
146
+ return re.sub(r"(?<!^)(?=[A-Z])", "_", s).lower()
147
+
148
+
149
+ def snake_to_pascal(s):
150
+ # Split the string at underscores and capitalize the first letter of each part
151
+ return "".join(word.capitalize() for word in s.split("_"))
152
+
153
+
143
154
  class PadGeometryTpe(Enum): # pragma: no cover
144
155
  Circle = 1
145
156
  Square = 2
@@ -1460,6 +1460,9 @@ class Modeler(object):
1460
1460
  self._pedb.active_layout, name, convert_py_list_to_net_list(pins)
1461
1461
  )
1462
1462
  if obj.IsNull():
1463
- self._logger.debug("Pin group creation returned Null obj.")
1464
- return False
1463
+ raise RuntimeError(f"Failed to create pin group {name}.")
1464
+ else:
1465
+ net_obj = [i.GetNet() for i in pins if not i.GetNet().IsNull()]
1466
+ if net_obj:
1467
+ obj.SetNet(net_obj[0])
1465
1468
  return self._pedb.siwave.pin_groups[name]
pyedb/edb_logger.py CHANGED
@@ -417,7 +417,7 @@ class EdbLogger(object):
417
417
 
418
418
  logger = logging.getLogger("Global")
419
419
  if any("aedt_logger" in str(i) for i in logger.filters):
420
- from pyaedt.generic.settings import settings as pyaedt_settings
420
+ from ansys.aedt.core.generic.settings import settings as pyaedt_settings
421
421
 
422
422
  from pyedb.generic.settings import settings as pyaedb_settings
423
423
 
pyedb/siwave.py CHANGED
@@ -15,6 +15,7 @@ import shutil
15
15
  import sys
16
16
  import tempfile
17
17
  import time
18
+ from typing import Optional, Union
18
19
  import warnings
19
20
 
20
21
  from pyedb import Edb
@@ -53,6 +54,15 @@ def wait_export_folder(flag, folder_path, time_sleep=0.5):
53
54
  time.sleep(time_sleep)
54
55
 
55
56
 
57
+ def parser_file_path(file_path):
58
+ if isinstance(file_path, Path):
59
+ file_path = str(file_path)
60
+
61
+ if not Path(file_path).root:
62
+ file_path = str(Path().cwd() / file_path)
63
+ return file_path
64
+
65
+
56
66
  class Siwave(object): # pragma no cover
57
67
  """Initializes SIwave based on the inputs provided and manages SIwave release and closing.
58
68
 
@@ -264,9 +274,9 @@ class Siwave(object): # pragma no cover
264
274
  ``True`` when successful, ``False`` when failed.
265
275
 
266
276
  """
267
-
268
- if os.path.exists(proj_path):
269
- open_result = self.oSiwave.OpenProject(proj_path)
277
+ file_path = parser_file_path(proj_path)
278
+ if os.path.exists(file_path):
279
+ open_result = self.oSiwave.OpenProject(file_path)
270
280
  self._oproject = self.oSiwave.GetActiveProject()
271
281
  return open_result
272
282
  else:
@@ -306,6 +316,22 @@ class Siwave(object): # pragma no cover
306
316
  self.oproject.Save()
307
317
  return True
308
318
 
319
+ def save(self, file_path: Optional[Union[str, Path]]):
320
+ """Save the project.
321
+
322
+ Parameters
323
+ ----------
324
+ file_path : str, optional
325
+ Full path to the project. The default is ``None``.
326
+ """
327
+
328
+ if file_path:
329
+ file_path = parser_file_path(file_path)
330
+ file_path = str(Path(file_path).with_suffix(".siw"))
331
+ self.oproject.ScrSaveProjectAs(file_path)
332
+ else:
333
+ self.oproject.Save()
334
+
309
335
  def close_project(self, save_project=False):
310
336
  """Close the project.
311
337
 
@@ -494,6 +520,8 @@ class Siwave(object): # pragma no cover
494
520
  """
495
521
  if isinstance(file_path, Path):
496
522
  file_path = str(file_path)
523
+ if not Path(file_path).root:
524
+ file_path = str(Path().cwd() / file_path)
497
525
  flag = self.oproject.ScrImportEDB(file_path)
498
526
  # self.save_project(self.di)
499
527
  if flag == 0:
@@ -510,8 +538,7 @@ class Siwave(object): # pragma no cover
510
538
  file_path : str
511
539
  Path to the configuration file.
512
540
  """
513
- if isinstance(file_path, Path):
514
- file_path = str(file_path)
541
+ file_path = parser_file_path(file_path)
515
542
 
516
543
  # temp_folder = tempfile.TemporaryDirectory(suffix=".ansys")
517
544
  # temp_edb = os.path.join(temp_folder.name, "temp.aedb")
@@ -536,8 +563,7 @@ class Siwave(object): # pragma no cover
536
563
  file_path : str
537
564
  Path to the configuration file.
538
565
  """
539
- if isinstance(file_path, Path):
540
- file_path = str(file_path)
566
+ file_path = parser_file_path(file_path)
541
567
 
542
568
  temp_folder = tempfile.TemporaryDirectory(suffix=".ansys")
543
569
  temp_edb = os.path.join(temp_folder.name, "temp.aedb")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyedb
3
- Version: 0.27.0
3
+ Version: 0.28.0
4
4
  Summary: Higher-Level Pythonic Ansys Electronics Data Base
5
5
  Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
6
6
  Maintainer-email: PyEDB developers <simon.vandenbrouck@ansys.com>
@@ -19,9 +19,9 @@ Requires-Dist: cffi>=1.16.0,<1.18; platform_system=='Linux'
19
19
  Requires-Dist: pywin32 >= 303;platform_system=='Windows'
20
20
  Requires-Dist: ansys-pythonnet >= 3.1.0rc3
21
21
  Requires-Dist: dotnetcore2 ==3.1.23;platform_system=='Linux'
22
- Requires-Dist: numpy>=1.20.0,<2.2
22
+ Requires-Dist: numpy>=1.20.0,<2
23
23
  Requires-Dist: pandas>=1.1.0,<2.3
24
- Requires-Dist: pydantic>=2.6.4,<2.9
24
+ Requires-Dist: pydantic>=2.6.4,<2.10
25
25
  Requires-Dist: Rtree >= 1.2.0
26
26
  Requires-Dist: toml == 0.10.2
27
27
  Requires-Dist: scikit-rf
@@ -37,7 +37,7 @@ Requires-Dist: numpydoc>=1.5.0,<1.9 ; extra == "doc"
37
37
  Requires-Dist: pypandoc>=1.10.0,<1.14 ; extra == "doc"
38
38
  Requires-Dist: recommonmark ; extra == "doc"
39
39
  Requires-Dist: Sphinx>=7.1.0,<8.1 ; extra == "doc"
40
- Requires-Dist: sphinx-autobuild==2024.2.4 ; extra == "doc" and ( python_version == '3.8')
40
+ Requires-Dist: sphinx-autobuild==2021.3.14 ; extra == "doc" and ( python_version == '3.8')
41
41
  Requires-Dist: sphinx-autobuild==2024.2.4 ; extra == "doc" and ( python_version > '3.8')
42
42
  Requires-Dist: sphinx-copybutton>=0.5.0,<0.6 ; extra == "doc"
43
43
  Requires-Dist: sphinx-gallery>=0.14.0,<0.18 ; extra == "doc"
@@ -1,39 +1,39 @@
1
- pyedb/__init__.py,sha256=KNfAzMP4AvkDL6n__iqyHGnx9lnekoi3WY3aEfthXKo,1521
2
- pyedb/edb_logger.py,sha256=yNkXnoL2me7ubLT6O6r6ElVnkZ1g8fmfFYC_2XJZ1Sw,14950
1
+ pyedb/__init__.py,sha256=i2Y8_oZHdAU8T5kqsiHeENkfm9LyD8AcJUy50FaBecM,1521
2
+ pyedb/edb_logger.py,sha256=7KXPvAMCKzlzJ5zioiNO5A3zkqbpCHhWHB4aXKfgu5Y,14959
3
3
  pyedb/exceptions.py,sha256=n94xluzUks6BA24vd_L6HkrvoP_H_l6__hQmqzdCyPo,111
4
- pyedb/siwave.py,sha256=OT1O7RSC78nmkhzDrwBo8mlWnsIyPCTy8nD1ZZm8BTk,16720
4
+ pyedb/siwave.py,sha256=6SL3PnklGMbVOsstvJJ1fx3D3YkBWr27pYDUG-U4VB8,17520
5
5
  pyedb/workflow.py,sha256=Y0ya4FUHwlSmoLP45zjdYLsSpyKduHUSpT9GGK9MGd8,814
6
6
  pyedb/component_libraries/ansys_components.py,sha256=O3ypt832IHY9zG2AD_yrRrbH2KH9P1yFaoi1EO6Zllw,4830
7
7
  pyedb/configuration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  pyedb/configuration/cfg_boundaries.py,sha256=ckb-OfaObItwy-xc0LqkHJyeCfKC5vg668olPjZbaKo,6647
9
9
  pyedb/configuration/cfg_common.py,sha256=5ne78TTA0wHpbi804nsUd9SPxNKZvut_X_Miu-xDRgk,1982
10
10
  pyedb/configuration/cfg_components.py,sha256=XGWvttmVpz7zHh9fpKFjsMiMy6KTP_GGsR3UGv8xuoI,7683
11
- pyedb/configuration/cfg_data.py,sha256=eSwdJ7ECP85oNGmmn3_1dK3lRQp4fS_uSYXD5TlNees,3631
11
+ pyedb/configuration/cfg_data.py,sha256=MQJJ-ztmxI1Gzii2xoepKSb7IWImnyeFBMCpWeAHGvs,3637
12
12
  pyedb/configuration/cfg_general.py,sha256=0dtd-rkQt2aYR3EOL0c3sNuDuJs7htRos1OWck3rxaI,1626
13
13
  pyedb/configuration/cfg_nets.py,sha256=18NezeNh0ZOwk2ehz3zWJF_xYR7IYCqGlpDfDt7Ilho,2349
14
- pyedb/configuration/cfg_operations.py,sha256=-Lliu2j7FrD1HI0exV2gg6ebNGYsSZLCP6N3idRWhcM,4472
14
+ pyedb/configuration/cfg_operations.py,sha256=iT7GW2XggtDjfS4vI4-2gS47Nai7mxfpKjG7V_8IM_0,4541
15
15
  pyedb/configuration/cfg_package_definition.py,sha256=f_RRT9R-3H5kHBlc4QSpjq9uQgYbaKQ78XXXrc_r3kg,5296
16
- pyedb/configuration/cfg_padstacks.py,sha256=5t799x_mfwLjCAic-B13v3I6FgDswysXdcKmeOxz4Uo,5571
17
- pyedb/configuration/cfg_pin_groups.py,sha256=Aq5rlUU2z9iNMv5cBBwHHTlSglw5Upm8EA4g7CQwD5o,3823
16
+ pyedb/configuration/cfg_padstacks.py,sha256=yRHWZJ1E6vcVxK-l1No_p33sEdPIOyqZvN5stNMqSLQ,5605
17
+ pyedb/configuration/cfg_pin_groups.py,sha256=b0H6NaPKJ5zlcXL9W2Q8_HbiLB8-OxaqjsM4wlqP2ic,3768
18
18
  pyedb/configuration/cfg_ports_sources.py,sha256=G2mX057QB3H3JUxAL0wDMDaHgabKFnht3iIyhTJvJU4,16356
19
19
  pyedb/configuration/cfg_s_parameter_models.py,sha256=NzS3eBjBSnd7ZDk_TsX04dqRcRXompjx1DxCe1UzWMw,2855
20
20
  pyedb/configuration/cfg_setup.py,sha256=SPpNRLJusB-Cz2fDQkc6gkdilUqIlbNngoxF3zySt6g,10115
21
21
  pyedb/configuration/cfg_spice_models.py,sha256=Q_5j2-V6cepSFcnijot8iypTqzanLp7HOz-agmnwKns,2570
22
22
  pyedb/configuration/cfg_stackup.py,sha256=CX7uNN5QRoYW_MOObknP8003YchTS7PH9Oee7FG0VKU,6589
23
- pyedb/configuration/configuration.py,sha256=fWYRDI0G4O8cyR1pk0_2RNqBOjKVL0oYRevIVjlV8fo,12944
23
+ pyedb/configuration/configuration.py,sha256=I-ivhVqnqEmDShTSACNqfZ0l49yJdNfyxNwHY-cMtkg,13502
24
24
  pyedb/dotnet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  pyedb/dotnet/clr_module.py,sha256=Mo13Of3DVSA5HR-5xZEXOiHApIKy52CUxtJ2gPkEu1A,3406
26
26
  pyedb/dotnet/edb.py,sha256=B7HYfgZkc-ezrdMIm3wInWAd5zw6ZMM5KdBG3H6y7L0,181695
27
- pyedb/dotnet/application/Variables.py,sha256=v_fxFJ6xjyyhk4uaMzWAbP-1FhXGuKsVNuyV1huaPME,77867
27
+ pyedb/dotnet/application/Variables.py,sha256=awNhyiLASBYrNjWIyW8IJowgqt7FfFPKF9UElRWyjZg,77750
28
28
  pyedb/dotnet/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  pyedb/dotnet/edb_core/__init__.py,sha256=nIRLJ8VZLcMAp12zmGsnZ5x2BEEl7q_Kj_KAOXxVjpQ,52
30
30
  pyedb/dotnet/edb_core/components.py,sha256=g2hPrTotCtHWA7y79ej1fw3UoY5KrgDwur3H3m-Vmfg,111194
31
- pyedb/dotnet/edb_core/general.py,sha256=1g2bUekyUbu8p8zCinT4eI7uqRGIK8tY8mfuFePGRGg,4415
31
+ pyedb/dotnet/edb_core/general.py,sha256=k2Bcr5VV-QUzEZlYorqYCX1ZchHBH7WqUvc8maMxId0,4716
32
32
  pyedb/dotnet/edb_core/hfss.py,sha256=C6-to6YKoruQjRWedLY7agkTVQv4Hb2U2qX-iPzHOI0,68655
33
33
  pyedb/dotnet/edb_core/layout_obj_instance.py,sha256=Pd8rfdO3b6HLFGwXBMw-tfE4LPIcW_9_X5KEdFaiito,1407
34
34
  pyedb/dotnet/edb_core/layout_validation.py,sha256=HxRPHEs9yMyz0XgIegWsb4nSV7hNYbO-xBJ-eFyNnQw,12609
35
35
  pyedb/dotnet/edb_core/materials.py,sha256=zzYWIJ5dvOIO2H2vREpRnwGDx0hEa5QhCsg_EJkydww,43222
36
- pyedb/dotnet/edb_core/modeler.py,sha256=iu16E6GXLlJZvsI_WTphyDDbFKX-i6_crFclTnNa--8,55316
36
+ pyedb/dotnet/edb_core/modeler.py,sha256=87amEA3xHszL52ae8i-7fAJzWL4Ntqp72omocNO5XAw,55442
37
37
  pyedb/dotnet/edb_core/net_class.py,sha256=4U6Cc1Gn7ZJ_ub9uKmtrsoz5wD1XS42afci3Y3ewRp0,11354
38
38
  pyedb/dotnet/edb_core/nets.py,sha256=WMKC9aKkmGP_NFqAkQpM8b4AjgDgjhrRXOz8VrN4yj8,41429
39
39
  pyedb/dotnet/edb_core/padstack.py,sha256=P4WqnMy_mRHHPNvLCG96eGGB8_8bSZPBVziStxGNd5I,63567
@@ -41,7 +41,7 @@ pyedb/dotnet/edb_core/siwave.py,sha256=4duoAsFCuPMNLxtMTEEVJCUaHKNkdbLDmtTXiD93V
41
41
  pyedb/dotnet/edb_core/stackup.py,sha256=b56leXg7X7dEVPP2DUD9n8LZIakWcjIsjiqqkIWsyZU,120035
42
42
  pyedb/dotnet/edb_core/cell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  pyedb/dotnet/edb_core/cell/connectable.py,sha256=gc5jhWx4DX718T7koL6oZZzfS4EdQNTiFX76ZJ2c83E,2864
44
- pyedb/dotnet/edb_core/cell/layout.py,sha256=DFZamAuiPI2pHtBWn2lPcwvhdpkVuWO-aYDuNTDmRQs,12623
44
+ pyedb/dotnet/edb_core/cell/layout.py,sha256=1BZ5j5sD7cuomG3-mV7Z7UBtfko39m6xm6Fjgwvn0zo,12696
45
45
  pyedb/dotnet/edb_core/cell/layout_obj.py,sha256=S42rdiI6gVqO77DV3ikc4YxTNufTuqW_X1G-2zkWArA,2765
46
46
  pyedb/dotnet/edb_core/cell/voltage_regulator.py,sha256=-uAzuyERV6ca0bFRzdH4SllcpGY2D9JEdpS7RYaQt6c,5387
47
47
  pyedb/dotnet/edb_core/cell/hierarchy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -60,7 +60,7 @@ pyedb/dotnet/edb_core/cell/terminal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
60
60
  pyedb/dotnet/edb_core/cell/terminal/bundle_terminal.py,sha256=qM0wEXkZ-DpoJ6vlVa560Ce8IgOdp4vyIJPedvoa3O0,1977
61
61
  pyedb/dotnet/edb_core/cell/terminal/edge_terminal.py,sha256=lafPRrvsDPYKcysvrkO-5tEZXF3h4IcTXdeJgTjleuI,2158
62
62
  pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py,sha256=XI7NiP1qT2aft7hjPK4gX42RzreiZ66aHXIHFPwUghs,3999
63
- pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py,sha256=3y2UXqg8a7W74pjzZDljB1joCPTtmOkrIKGophDdgw4,2783
63
+ pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py,sha256=Xupr55vseJsAR6y62Ekv1Kie_ILc6RVNzT3Sgxdi7X4,2753
64
64
  pyedb/dotnet/edb_core/cell/terminal/point_terminal.py,sha256=S3aCAuFc_QA36PVn2Cdb9L4dO3T4IikwyEVcP1FOW3I,2597
65
65
  pyedb/dotnet/edb_core/cell/terminal/terminal.py,sha256=WoNS05-wSktF93MvDUjNQw9MMC3e18UGcsBKsy2fo68,19130
66
66
  pyedb/dotnet/edb_core/definition/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -79,9 +79,9 @@ pyedb/dotnet/edb_core/edb_data/edbvalue.py,sha256=Vj_11HXsQUNavizKp5FicORm6cjhXR
79
79
  pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py,sha256=hKFHWUl0_OCMEZJbQn5c8Y1a-BYKr8nAycIlrCoeufk,13005
80
80
  pyedb/dotnet/edb_core/edb_data/layer_data.py,sha256=2K1rvBXAWg3s8paNU6TPNb5tC1B3bRHmiUZjVsoX_Z8,26001
81
81
  pyedb/dotnet/edb_core/edb_data/nets_data.py,sha256=Ifi5uSfnOuTLwesO9TS3_F-qa_8rpPXrJy6W5lvIWik,9684
82
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py,sha256=VL3mmTHTbSNjODoGC0kklakJBdTDlukGQng931ZIJdE,76755
82
+ pyedb/dotnet/edb_core/edb_data/padstacks_data.py,sha256=W6yX4KxDdD7OiPQjuLEsXivKNp3yDoCzWNliEDHeRaM,85380
83
83
  pyedb/dotnet/edb_core/edb_data/ports.py,sha256=wr2RQi8VExuNIVmnp7c4VpTIhODgthmJmHr01zO4ueo,8873
84
- pyedb/dotnet/edb_core/edb_data/primitives_data.py,sha256=CC-uSLponRiJKGh1rqc6FsITpBB5on0jP3M7YAGArfM,15449
84
+ pyedb/dotnet/edb_core/edb_data/primitives_data.py,sha256=zDgVbOcvgc7fbpLnCcCHURV9_ePYT4R129kAhSJRy9A,15467
85
85
  pyedb/dotnet/edb_core/edb_data/raptor_x_simulation_setup_data.py,sha256=P37-OIsc8TuTC_s3CXRmvZcJqxAftHA7SATfEyoAnMM,20953
86
86
  pyedb/dotnet/edb_core/edb_data/simulation_configuration.py,sha256=Z_Iuh7qgj9s0PwmlOOdBOC47imBTgWPAWt8KxGNZmZQ,100432
87
87
  pyedb/dotnet/edb_core/edb_data/sources.py,sha256=jzC6p-fiuPEvZn3b9z1-X5UexW5jd48jZRamXillnXI,15700
@@ -185,7 +185,7 @@ pyedb/misc/siw_feature_config/xtalk_scan/scan_config.py,sha256=YmYI6WTQulL5Uf8Wx
185
185
  pyedb/misc/siw_feature_config/xtalk_scan/td_xtalk_config.py,sha256=KHa-UqcXuabiVfT2CV-UvWl5Q2qGYHF2Ye9azcAlnXc,3966
186
186
  pyedb/modeler/geometry_operators.py,sha256=g_Sy7a6R23sP6RtboJn1rl8uTuo8oeLmMF21rNkzwjk,74198
187
187
  pyedb/siwave_core/icepak.py,sha256=WnZ-t8mik7LDY06V8hZFV-TxRZJQWK7bu_8Ichx-oBs,5206
188
- pyedb-0.27.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
189
- pyedb-0.27.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
190
- pyedb-0.27.0.dist-info/METADATA,sha256=hY877_LGGnjb-1CLwMRtd6PbPRVk7_L7-g_ZbivQucw,8388
191
- pyedb-0.27.0.dist-info/RECORD,,
188
+ pyedb-0.28.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
189
+ pyedb-0.28.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
190
+ pyedb-0.28.0.dist-info/METADATA,sha256=12aP4dKjrhx21He3-0FQDDWfpDMkTHmpM8b1IF2pckU,8388
191
+ pyedb-0.28.0.dist-info/RECORD,,
File without changes