pyedb 0.29.0__py3-none-any.whl → 0.30.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
@@ -3,14 +3,21 @@ import os
3
3
  import sys
4
4
  import warnings
5
5
 
6
- if os.name == "nt":
7
- os.environ["PYTHONMALLOC"] = "malloc"
6
+ # if os.name == "nt":
7
+ # os.environ["PYTHONMALLOC"] = "malloc"
8
8
 
9
9
  # By default we use pyedb legacy implementation
10
10
  if "PYEDB_USE_DOTNET" not in os.environ:
11
11
  os.environ["PYEDB_USE_DOTNET"] = "0"
12
12
 
13
13
  LATEST_DEPRECATED_PYTHON_VERSION = (3, 7)
14
+ LINUX_WARNING = (
15
+ "Due to compatibility issues between .NET Core and libssl on some Linux versions, "
16
+ "for example Ubuntu 22.04, we are going to stop depending on `dotnetcore2`."
17
+ "Instead of using this package which embeds .NET Core 3, users will be required to "
18
+ "install .NET themselves. For more information, see "
19
+ "https://edb.docs.pyansys.com/version/stable/build_breaking_change.html"
20
+ )
14
21
 
15
22
 
16
23
  def deprecation_warning():
@@ -39,12 +46,31 @@ def deprecation_warning():
39
46
  warnings.showwarning = existing_showwarning
40
47
 
41
48
 
49
+ def linux_warning():
50
+ """Warning message informing Linux users a future breaking change is coming."""
51
+ # Store warnings showwarning
52
+ existing_showwarning = warnings.showwarning
53
+
54
+ # Define and use custom showwarning
55
+ def custom_show_warning(message, category, filename, lineno, file=None, line=None):
56
+ """Custom warning used to remove <stdin>:loc: pattern."""
57
+ print("{}: {}".format(category.__name__, message))
58
+
59
+ warnings.showwarning = custom_show_warning
60
+
61
+ if os.name == "posix":
62
+ warnings.warn(LINUX_WARNING, FutureWarning)
63
+
64
+ # Restore warnings showwarning
65
+ warnings.showwarning = existing_showwarning
66
+
67
+
42
68
  deprecation_warning()
43
69
 
44
70
  #
45
71
 
46
72
  pyedb_path = os.path.dirname(__file__)
47
- __version__ = "0.29.0"
73
+ __version__ = "0.30.0"
48
74
  version = __version__
49
75
 
50
76
  #
@@ -53,9 +53,9 @@ class CfgComponents:
53
53
  self.components = [CfgComponent(**comp) for comp in components_data]
54
54
 
55
55
  def apply(self):
56
- comps_in_db = self._pedb.components.components
56
+ comps_in_db = self._pedb.components
57
57
  for comp in self.components:
58
- c_db = comps_in_db[comp.reference_designator]
58
+ c_db = comps_in_db.instances[comp.reference_designator]
59
59
  if comp.definition:
60
60
  c_db.definition = comp.definition
61
61
  if comp.type:
@@ -65,7 +65,7 @@ class CfgComponents:
65
65
  if comp.port_properties:
66
66
  c_db.port_properties = comp.port_properties
67
67
  if comp.ic_die_properties:
68
- c_db.set_ic_die_properties = comp.ic_die_properties
68
+ c_db.ic_die_properties = comp.ic_die_properties
69
69
  if comp.pin_pair_model:
70
70
  c_db.model_properties = {"pin_pair_model": comp.pin_pair_model}
71
71
  if comp.spice_model:
@@ -41,7 +41,7 @@ class CfgData(object):
41
41
 
42
42
  def __init__(self, pedb, **kwargs):
43
43
  self._pedb = pedb
44
- self.general = CfgGeneral(self, kwargs.get("general", None))
44
+ self.general = CfgGeneral(self._pedb, kwargs.get("general", {}))
45
45
 
46
46
  self.boundaries = CfgBoundaries(self._pedb, kwargs.get("boundaries", {}))
47
47
 
@@ -24,11 +24,22 @@
24
24
  class CfgGeneral:
25
25
  """Manage configuration general settings."""
26
26
 
27
- def __init__(self, pdata, general_dict):
28
- self._pedb = pdata._pedb
29
- self.spice_model_library = ""
30
- self.s_parameter_library = ""
31
- if general_dict:
32
- self._general_dict = general_dict
33
- self.spice_model_library = self._general_dict.get("spice_model_library", "")
34
- self.s_parameter_library = self._general_dict.get("s_parameter_library", "")
27
+ def __init__(self, pedb, data):
28
+ self._pedb = pedb
29
+ self.spice_model_library = data.get("spice_model_library", "")
30
+ self.s_parameter_library = data.get("s_parameter_library", "")
31
+ self.anti_pads_always_on = data.get("anti_pads_always_on", False)
32
+ self.suppress_pads = data.get("suppress_pads", True)
33
+
34
+ def apply(self):
35
+ self._pedb.design_options.antipads_always_on = self.anti_pads_always_on
36
+ self._pedb.design_options.suppress_pads = self.suppress_pads
37
+
38
+ def get_data_from_db(self):
39
+ self.anti_pads_always_on = self._pedb.design_options.antipads_always_on
40
+ self.suppress_pads = self._pedb.design_options.suppress_pads
41
+
42
+ data = {}
43
+ data["anti_pads_always_on"] = self.anti_pads_always_on
44
+ data["suppress_pads"] = self.suppress_pads
45
+ return data
@@ -73,14 +73,21 @@ class CfgPadstacks:
73
73
  definitions.append(i.get_attributes())
74
74
  data["definitions"] = definitions
75
75
 
76
- instances_layout = self._pedb.padstacks.instances_by_name
77
- for name, obj in instances_layout.items():
76
+ for obj in self._pedb.layout.padstack_instances:
77
+ temp = obj.properties
78
78
  self.instances.append(
79
- Instance(name=name, definition=obj.padstack_definition, backdrill_parameters=obj.backdrill_parameters)
79
+ Instance(
80
+ name=temp["name"],
81
+ definition=temp["definition"],
82
+ backdrill_parameters=temp["backdrill_parameters"],
83
+ id=temp["id"],
84
+ position=temp["position"],
85
+ rotation=temp["rotation"],
86
+ )
80
87
  )
81
88
  instances = []
82
89
  for i in self.instances:
83
- instances.append(i.get_attributes())
90
+ instances.append(i.get_attributes("id"))
84
91
  data["instances"] = instances
85
92
  return data
86
93
 
@@ -104,3 +111,6 @@ class Instance(CfgBase):
104
111
  self.name = kwargs["name"]
105
112
  self.definition = kwargs.get("definition", None)
106
113
  self.backdrill_parameters = kwargs.get("backdrill_parameters", None)
114
+ self.id = kwargs.get("id", None)
115
+ self.position = kwargs.get("position", [])
116
+ self.rotation = kwargs.get("rotation", None)
@@ -177,6 +177,11 @@ class CfgSetups:
177
177
  def get_data_from_db(self):
178
178
  setups = []
179
179
  for _, s in self._pedb.setups.items():
180
+ if float(self._pedb.edbversion) < 2025.1:
181
+ if not s.type == "hfss":
182
+ self._pedb.logger.warning("Only HFSS setups are exported in 2024 R2 and earlier version.")
183
+ continue
184
+
180
185
  stp = {}
181
186
  if s.type == "hfss":
182
187
  for p_name in CfgHFSSSetup(self._pedb).__dict__:
@@ -44,6 +44,7 @@ class CfgLayer(CfgBase):
44
44
  self.material = kwargs.get("material", None)
45
45
  self.fill_material = kwargs.get("fill_material", None)
46
46
  self.thickness = kwargs.get("thickness", None)
47
+ self.roughness = kwargs.get("roughness", None)
47
48
 
48
49
 
49
50
  class CfgStackup:
@@ -139,12 +140,7 @@ class CfgStackup:
139
140
  def get_layers_from_db(self):
140
141
  layers = []
141
142
  for name, obj in self._pedb.stackup.all_layers.items():
142
- layer = {}
143
- for p_name in CfgLayer().__dict__:
144
- p_value = getattr(obj, p_name, None)
145
- if p_value is not None:
146
- layer[p_name] = getattr(obj, p_name)
147
- layers.append(layer)
143
+ layers.append(obj.properties)
148
144
  return layers
149
145
 
150
146
  def get_data_from_db(self):
@@ -106,6 +106,9 @@ class Configuration:
106
106
  def run(self, **kwargs):
107
107
  """Apply configuration settings to the current design"""
108
108
 
109
+ if self.cfg_data.general:
110
+ self.cfg_data.general.apply()
111
+
109
112
  # Configure boundary settings
110
113
  if self.cfg_data.boundaries:
111
114
  self.cfg_data.boundaries.apply()
@@ -272,6 +275,8 @@ class Configuration:
272
275
  """
273
276
  self._pedb.logger.info("Getting data from layout database.")
274
277
  data = {}
278
+ if kwargs.get("general", False):
279
+ data["general"] = self.cfg_data.general.get_data_from_db()
275
280
  if kwargs.get("stackup", False):
276
281
  data["stackup"] = self.cfg_data.stackup.get_data_from_db()
277
282
  if kwargs.get("package_definitions", False):
@@ -314,6 +319,7 @@ class Configuration:
314
319
  boundaries=True,
315
320
  s_parameters=True,
316
321
  padstacks=True,
322
+ general=True,
317
323
  ):
318
324
  """Export the configuration data from layout to a file.
319
325
 
@@ -345,6 +351,8 @@ class Configuration:
345
351
  Whether to export s_parameters.
346
352
  padstacks : bool
347
353
  Whether to export padstacks.
354
+ general : bool
355
+ Whether to export general information.
348
356
  Returns
349
357
  -------
350
358
  bool
@@ -352,7 +360,7 @@ class Configuration:
352
360
  data = self.get_data_from_db(
353
361
  stackup=stackup,
354
362
  package_definitions=package_definitions,
355
- setups=False,
363
+ setups=setups,
356
364
  sources=sources,
357
365
  ports=ports,
358
366
  nets=nets,
@@ -362,6 +370,7 @@ class Configuration:
362
370
  boundaries=boundaries,
363
371
  s_parameters=s_parameters,
364
372
  padstacks=padstacks,
373
+ general=general,
365
374
  )
366
375
 
367
376
  file_path = file_path if isinstance(file_path, Path) else Path(file_path)
pyedb/dotnet/edb.py CHANGED
@@ -558,6 +558,10 @@ class Edb(Database):
558
558
  for cell in list(self.top_circuit_cells):
559
559
  if cell.GetName() == self.cellname:
560
560
  self._active_cell = cell
561
+ if self._active_cell is None:
562
+ for cell in list(self.circuit_cells):
563
+ if cell.GetName() == self.cellname:
564
+ self._active_cell = cell
561
565
  # if self._active_cell is still None, set it to default cell
562
566
  if self._active_cell is None:
563
567
  self._active_cell = list(self.top_circuit_cells)[0]
@@ -1455,12 +1459,12 @@ class Edb(Database):
1455
1459
  def import_gds_file(
1456
1460
  self,
1457
1461
  inputGDS,
1458
- WorkDir=None,
1459
1462
  anstranslator_full_path="",
1460
1463
  use_ppe=False,
1461
1464
  control_file=None,
1462
1465
  tech_file=None,
1463
1466
  map_file=None,
1467
+ layer_filter=None,
1464
1468
  ):
1465
1469
  """Import a GDS file and generate an ``edb.def`` file in the working directory.
1466
1470
 
@@ -1471,10 +1475,6 @@ class Edb(Database):
1471
1475
  ----------
1472
1476
  inputGDS : str
1473
1477
  Full path to the GDS file.
1474
- WorkDir : str, optional
1475
- Directory in which to create the ``aedb`` folder. The default value is ``None``,
1476
- in which case the AEDB file is given the same name as the GDS file. Only the extension
1477
- differs.
1478
1478
  anstranslator_full_path : str, optional
1479
1479
  Full path to the Ansys translator.
1480
1480
  use_ppe : bool, optional
@@ -1484,31 +1484,67 @@ class Edb(Database):
1484
1484
  the XML file in the same directory as the GDS file. To succeed, the XML file and GDS file must
1485
1485
  have the same name. Only the extension differs.
1486
1486
  tech_file : str, optional
1487
- Technology file. It uses Helic to convert tech file to xml and then imports the gds. Works on Linux only.
1487
+ Technology file. For versions<2024.1 it uses Helic to convert tech file to xml and then imports
1488
+ the gds. Works on Linux only.
1489
+ For versions>=2024.1 it can directly parse through supported foundry tech files.
1488
1490
  map_file : str, optional
1489
1491
  Layer map file.
1490
-
1491
- Returns
1492
- -------
1493
- bool
1494
- ``True`` when successful, ``False`` when failed.
1492
+ layer_filter:str,optional
1493
+ Layer filter file.
1495
1494
 
1496
1495
  """
1497
- if not is_linux and tech_file:
1498
- self.logger.error("Technology files are supported only in Linux. Use control file instead.")
1499
- return False
1500
1496
  control_file_temp = os.path.join(tempfile.gettempdir(), os.path.split(inputGDS)[-1][:-3] + "xml")
1501
- ControlFile(xml_input=control_file, tecnhology=tech_file, layer_map=map_file).write_xml(control_file_temp)
1502
- if self.import_layout_pcb(
1503
- inputGDS,
1504
- working_dir=WorkDir,
1505
- anstranslator_full_path=anstranslator_full_path,
1506
- use_ppe=use_ppe,
1507
- control_file=control_file_temp,
1508
- ):
1509
- return True
1497
+ if float(self.edbversion) < 2024.1:
1498
+ if not is_linux and tech_file:
1499
+ self.logger.error("Technology files are supported only in Linux. Use control file instead.")
1500
+ return False
1501
+
1502
+ ControlFile(xml_input=control_file, tecnhology=tech_file, layer_map=map_file).write_xml(control_file_temp)
1503
+ if self.import_layout_pcb(
1504
+ inputGDS,
1505
+ anstranslator_full_path=anstranslator_full_path,
1506
+ use_ppe=use_ppe,
1507
+ control_file=control_file_temp,
1508
+ ):
1509
+ return True
1510
+ else:
1511
+ return False
1510
1512
  else:
1511
- return False
1513
+ temp_map_file = os.path.splitext(inputGDS)[0] + ".map"
1514
+ temp_layermap_file = os.path.splitext(inputGDS)[0] + ".layermap"
1515
+
1516
+ if map_file is None:
1517
+ if os.path.isfile(temp_map_file):
1518
+ map_file = temp_map_file
1519
+ elif os.path.isfile(temp_layermap_file):
1520
+ map_file = temp_layermap_file
1521
+ else:
1522
+ self.logger.error("Unable to define map file.")
1523
+
1524
+ if tech_file is None:
1525
+ if control_file is None:
1526
+ temp_control_file = os.path.splitext(inputGDS)[0] + ".xml"
1527
+ if os.path.isfile(temp_control_file):
1528
+ control_file = temp_control_file
1529
+ else:
1530
+ self.logger.error("Unable to define control file.")
1531
+
1532
+ command = [anstranslator_full_path, inputGDS, f'-g="{map_file}"', f'-c="{control_file}"']
1533
+ else:
1534
+ command = [
1535
+ anstranslator_full_path,
1536
+ inputGDS,
1537
+ f'-o="{control_file_temp}"' f'-t="{tech_file}"',
1538
+ f'-g="{map_file}"',
1539
+ f'-f="{layer_filter}"',
1540
+ ]
1541
+
1542
+ result = subprocess.run(command, capture_output=True, text=True, shell=True)
1543
+ print(result.stdout)
1544
+ print(command)
1545
+ temp_inputGDS = inputGDS.split(".gds")[0]
1546
+ self.edbpath = temp_inputGDS + ".aedb"
1547
+ return self.open_edb()
1512
1548
 
1513
1549
  def _create_extent(
1514
1550
  self,
@@ -2208,7 +2244,7 @@ class Edb(Database):
2208
2244
  pins_to_preserve = []
2209
2245
  nets_to_preserve = []
2210
2246
  if preserve_components_with_model:
2211
- for el in self.components.instances.values():
2247
+ for el in self.layout.groups:
2212
2248
  if el.model_type in [
2213
2249
  "SPICEModel",
2214
2250
  "SParameterModel",
@@ -2237,23 +2273,41 @@ class Edb(Database):
2237
2273
  reference_pinsts = []
2238
2274
  reference_prims = []
2239
2275
  reference_paths = []
2240
- for i in self.padstacks.instances.values():
2241
- net_name = i.net_name
2242
- id = i.id
2276
+ pins_to_delete = []
2277
+
2278
+ def check_instances(item):
2279
+ net_name = item.net_name
2280
+ id = item.id
2243
2281
  if net_name not in all_list and id not in pins_to_preserve:
2244
- i.delete()
2282
+ pins_to_delete.append(item)
2245
2283
  elif net_name in reference_list and id not in pins_to_preserve:
2246
- reference_pinsts.append(i)
2247
- for i in self.modeler.primitives:
2248
- if i:
2249
- net_name = i.net_name
2284
+ reference_pinsts.append(item)
2285
+
2286
+ with ThreadPoolExecutor(number_of_threads) as pool:
2287
+ pool.map(lambda item: check_instances(item), self.layout.padstack_instances)
2288
+
2289
+ for i in pins_to_delete:
2290
+ i.delete()
2291
+
2292
+ prim_to_delete = []
2293
+
2294
+ def check_prims(item):
2295
+ if item:
2296
+ net_name = item.net_name
2250
2297
  if net_name not in all_list:
2251
- i.delete()
2252
- elif net_name in reference_list and not i.is_void:
2253
- if keep_lines_as_path and i.type == "Path":
2254
- reference_paths.append(i)
2298
+ prim_to_delete.append(item)
2299
+ elif net_name in reference_list and not item.is_void:
2300
+ if keep_lines_as_path and item.type == "Path":
2301
+ reference_paths.append(item)
2255
2302
  else:
2256
- reference_prims.append(i)
2303
+ reference_prims.append(item)
2304
+
2305
+ with ThreadPoolExecutor(number_of_threads) as pool:
2306
+ pool.map(lambda item: check_prims(item), self.modeler.primitives)
2307
+
2308
+ for i in prim_to_delete:
2309
+ i.delete()
2310
+
2257
2311
  self.logger.info_timer("Net clean up")
2258
2312
  self.logger.reset_timer()
2259
2313
 
@@ -2298,7 +2352,7 @@ class Edb(Database):
2298
2352
  if not _poly or _poly.IsNull():
2299
2353
  self._logger.error("Failed to create Extent.")
2300
2354
  return []
2301
- self.logger.info_timer("Expanded Net Polygon Creation")
2355
+ self.logger.info_timer("Extent Creation")
2302
2356
  self.logger.reset_timer()
2303
2357
  _poly_list = convert_py_list_to_net_list([_poly])
2304
2358
  prims_to_delete = []
@@ -2381,20 +2435,17 @@ class Edb(Database):
2381
2435
  for pin in pins_to_delete:
2382
2436
  pin.delete()
2383
2437
 
2384
- self.logger.info_timer(
2385
- "Padstack Instances removal completed. {} instances removed.".format(len(pins_to_delete))
2386
- )
2438
+ self.logger.info_timer("{} Padstack Instances deleted.".format(len(pins_to_delete)))
2387
2439
  self.logger.reset_timer()
2388
2440
 
2389
- # with ThreadPoolExecutor(number_of_threads) as pool:
2390
- # pool.map(lambda item: clip_path(item), reference_paths)
2391
-
2392
- for item in reference_paths:
2393
- clip_path(item)
2394
- for prim in reference_prims: # removing multithreading as failing with new layer from primitive
2395
- clean_prim(prim)
2396
- # with ThreadPoolExecutor(number_of_threads) as pool:
2397
- # pool.map(lambda item: clean_prim(item), reference_prims)
2441
+ with ThreadPoolExecutor(number_of_threads) as pool:
2442
+ pool.map(lambda item: clip_path(item), reference_paths)
2443
+ with ThreadPoolExecutor(number_of_threads) as pool:
2444
+ pool.map(lambda item: clean_prim(item), reference_prims)
2445
+ # for item in reference_paths:
2446
+ # clip_path(item)
2447
+ # for prim in reference_prims: # removing multithreading as failing with new layer from primitive
2448
+ # clean_prim(prim)
2398
2449
 
2399
2450
  for el in poly_to_create:
2400
2451
  self.modeler.create_polygon(el[0], el[1], net_name=el[2], voids=el[3])
@@ -2402,7 +2453,7 @@ class Edb(Database):
2402
2453
  for prim in prims_to_delete:
2403
2454
  prim.delete()
2404
2455
 
2405
- self.logger.info_timer("Primitives cleanup completed. {} primitives deleted.".format(len(prims_to_delete)))
2456
+ self.logger.info_timer("{} Primitives deleted.".format(len(prims_to_delete)))
2406
2457
  self.logger.reset_timer()
2407
2458
 
2408
2459
  i = 0
@@ -2411,7 +2462,7 @@ class Edb(Database):
2411
2462
  val.edbcomponent.Delete()
2412
2463
  i += 1
2413
2464
  i += 1
2414
- self.logger.info("Deleted {} additional components".format(i))
2465
+ self.logger.info("{} components deleted".format(i))
2415
2466
  if remove_single_pin_components:
2416
2467
  self.components.delete_single_pin_rlc()
2417
2468
  self.logger.info_timer("Single Pins components deleted")
@@ -1109,7 +1109,7 @@ class EDBComponent(Group):
1109
1109
  die_type = pascal_to_snake(ic_die_prop.GetType().ToString())
1110
1110
  temp["type"] = die_type
1111
1111
  if not die_type == "no_die":
1112
- temp["orientation"] = pascal_to_snake(ic_die_prop.GetOrientation())
1112
+ temp["orientation"] = pascal_to_snake(ic_die_prop.GetOrientation().ToString())
1113
1113
  if die_type == "wire_bond":
1114
1114
  temp["height"] = ic_die_prop.GetHeightValue().ToString()
1115
1115
  return temp
@@ -1123,10 +1123,13 @@ class EDBComponent(Group):
1123
1123
  else:
1124
1124
  ic_die_prop = cp.GetDieProperty().Clone()
1125
1125
  die_type = kwargs.get("type")
1126
+ ic_die_prop.SetType(getattr(self._edb.definition.DieType, snake_to_pascal(die_type)))
1126
1127
  if not die_type == "no_die":
1127
1128
  orientation = kwargs.get("orientation")
1128
1129
  if orientation:
1129
- ic_die_prop.SetOrientation(getattr(self._edb.definition.DieType, snake_to_pascal(die_type)))
1130
+ ic_die_prop.SetOrientation(
1131
+ getattr(self._edb.definition.DieOrientation, snake_to_pascal(orientation))
1132
+ )
1130
1133
  if die_type == "wire_bond":
1131
1134
  height = kwargs.get("height")
1132
1135
  if height:
@@ -230,11 +230,7 @@ class Layout(ObjBase):
230
230
  -------
231
231
  list of :class:`dotnet.edb_core.dotnet.primitive.PrimitiveDotNet` cast objects.
232
232
  """
233
- prims = []
234
- for p in self._edb_object.Primitives:
235
- obj = primitive_cast(self._pedb, p)
236
- prims.append(obj)
237
- return prims
233
+ return [primitive_cast(self._pedb, p) for p in self._edb_object.Primitives]
238
234
 
239
235
  @property
240
236
  def bondwires(self):
@@ -249,14 +245,7 @@ class Layout(ObjBase):
249
245
 
250
246
  @property
251
247
  def groups(self):
252
- temp = []
253
- for i in list(self._edb_object.Groups):
254
- group_type = i.ToString().split(".")[-1].lower()
255
- if group_type == "component":
256
- temp.append(EDBComponent(self._pedb, i))
257
- else:
258
- pass
259
- return temp
248
+ return [EDBComponent(self._pedb, i) for i in self._edb_object.Groups if i.ToString().endswith(".Component")]
260
249
 
261
250
  @property
262
251
  def pin_groups(self):
@@ -43,8 +43,6 @@ class Primitive(Connectable):
43
43
  def __init__(self, pedb, edb_object):
44
44
  super().__init__(pedb, edb_object)
45
45
  self._app = self._pedb
46
- self._core_stackup = pedb.stackup
47
- self._core_net = pedb.nets
48
46
  self.primitive_object = self._edb_object
49
47
 
50
48
  bondwire_type = self._pedb._edb.Cell.Primitive.BondwireType
@@ -62,6 +60,14 @@ class Primitive(Connectable):
62
60
  "rectangle": bondwire_cross_section_type.BondwireRectangle,
63
61
  }
64
62
 
63
+ @property
64
+ def _core_stackup(self):
65
+ return self._app.stackup
66
+
67
+ @property
68
+ def _core_net(self):
69
+ return self._app.nets
70
+
65
71
  @property
66
72
  def type(self):
67
73
  """Return the type of the primitive.
@@ -313,8 +313,7 @@ class Components(object):
313
313
  # self._logger.info("Refreshing the Components dictionary.")
314
314
  self._cmp = {}
315
315
  for i in self._pedb.layout.groups:
316
- if i.group_type == "component":
317
- self._cmp[i.name] = i
316
+ self._cmp[i.name] = i
318
317
  return True
319
318
 
320
319
  @property
@@ -58,6 +58,8 @@ class LayerEdbClass(object):
58
58
  for k, v in kwargs.items():
59
59
  if k in dir(self):
60
60
  self.__setattr__(k, v)
61
+ elif k == "roughness":
62
+ self.properties = {"roughness": v}
61
63
  else:
62
64
  self._pedb.logger.error(f"{k} is not a valid layer attribute")
63
65
 
@@ -178,7 +180,7 @@ class LayerEdbClass(object):
178
180
  RGB.
179
181
  """
180
182
  layer_color = self._edb_layer.GetColor()
181
- return layer_color.Item1, layer_color.Item2, layer_color.Item3
183
+ return [layer_color.Item1, layer_color.Item2, layer_color.Item3]
182
184
 
183
185
  @color.setter
184
186
  def color(self, rgb):
@@ -238,6 +240,26 @@ class LayerEdbClass(object):
238
240
  self._type = value
239
241
  self._pedb.stackup._set_layout_stackup(layer_clone, "change_attribute")
240
242
 
243
+ @property
244
+ def properties(self):
245
+ data = {}
246
+ data["name"] = self.name
247
+ data["type"] = self.type
248
+ data["color"] = self.color
249
+ return data
250
+
251
+ @properties.setter
252
+ def properties(self, params):
253
+ name = params.get("name", "")
254
+ if name:
255
+ self.name = name
256
+ type = params.get("type", "")
257
+ if type:
258
+ self.type = type
259
+ color = params.get("color", "")
260
+ if color:
261
+ self.color = color
262
+
241
263
 
242
264
  class StackupLayerEdbClass(LayerEdbClass):
243
265
  def __init__(self, pedb, edb_object=None, name="", layer_type="signal", **kwargs):
@@ -705,3 +727,75 @@ class StackupLayerEdbClass(LayerEdbClass):
705
727
  layer["side_hallhuray_surface_ratio"],
706
728
  apply_on_surface="side",
707
729
  )
730
+
731
+ @property
732
+ def properties(self):
733
+ data = {}
734
+ data["name"] = self.name
735
+ data["type"] = self.type
736
+ data["material"] = self.material
737
+ data["fill_material"] = self.fill_material
738
+ data["thickness"] = self._edb_object.GetThicknessValue().ToString()
739
+ data["color"] = self.color
740
+
741
+ roughness = {}
742
+ for region in ["top", "bottom", "side"]:
743
+ temp = {}
744
+ r_model = self._edb_object.GetRoughnessModel(
745
+ getattr(self._pedb._edb.Cell.RoughnessModel.Region, region.capitalize())
746
+ )
747
+ if r_model.ToString().split(".")[-1] == "HurrayRoughnessModel":
748
+ temp["model"] = "huray"
749
+ temp["nodule_radius"] = r_model.NoduleRadius.ToString()
750
+ temp["surface_ratio"] = r_model.SurfaceRatio.ToString()
751
+ else:
752
+ temp["model"] = "groisse"
753
+ temp["roughness"] = r_model.Roughness.ToString()
754
+ roughness[region] = temp
755
+ roughness["enabled"] = self._edb_object.IsRoughnessEnabled()
756
+ data["roughness"] = roughness
757
+ return data
758
+
759
+ @properties.setter
760
+ def properties(self, params):
761
+ name = params.get("name")
762
+ if name:
763
+ self.name = name
764
+ type = params.get("type")
765
+ if type:
766
+ self.type = type
767
+ material = params.get("material")
768
+ if material:
769
+ self.material = material
770
+ fill_material = params.get("fill_material")
771
+ if fill_material:
772
+ self.fill_material = fill_material
773
+ thickness = params.get("thickness")
774
+ if thickness:
775
+ self.thickness = self._pedb.edb_value(thickness)
776
+ color = params.get("color")
777
+ if color:
778
+ self.color = color
779
+ roughness = params.get("roughness")
780
+ if roughness:
781
+ layer_clone = self._edb_layer
782
+ layer_clone.SetRoughnessEnabled(roughness["enabled"])
783
+ for region in ["top", "bottom", "side"]:
784
+ r_data = roughness.get(region)
785
+ if r_data:
786
+ if r_data["model"] == "huray":
787
+ r_model = self._pedb._edb.Cell.HurrayRoughnessModel(
788
+ self._pedb.edb_value(r_data["nodule_radius"]), self._pedb.edb_value(r_data["surface_ratio"])
789
+ )
790
+ else:
791
+ r_model = self._pedb._edb.Cell.GroisseRoughnessModel(self._pedb.edb_value(r_data["roughness"]))
792
+ else:
793
+ r_model = self._pedb._edb.Cell.HurrayRoughnessModel(
794
+ self._pedb.edb_value("0"), self._pedb.edb_value("0")
795
+ )
796
+ layer_clone.SetRoughnessModel(
797
+ getattr(self._pedb._edb.Cell.RoughnessModel.Region, region.capitalize()), r_model
798
+ )
799
+ self._pedb.stackup._set_layout_stackup(layer_clone, "change_attribute")
800
+
801
+ layer_clone.SetRoughnessEnabled(True)
@@ -499,7 +499,8 @@ class EDBPadstack(object):
499
499
  self._ppadstack._pedb._edb.Definition.PadType.RegularPad,
500
500
  self._ppadstack._pedb._edb.Definition.PadType.AntiPad,
501
501
  self._ppadstack._pedb._edb.Definition.PadType.ThermalPad,
502
- self._ppadstack._pedb._edb.Definition.PadType.Hole,
502
+ # self._ppadstack._pedb._edb.Definition.PadType.Hole,
503
+ # This property doesn't appear in UI. It is unclear what it is used for. Suppressing this property for now.
503
504
  ]
504
505
  data = {}
505
506
  for pad_type in pad_type_list:
@@ -588,15 +589,14 @@ class EDBPadstack(object):
588
589
  continue
589
590
 
590
591
  # Set pad parameters for the current layer
591
- default = original_params[pad_type_name]
592
592
  pdef_data.SetPadParameters(
593
593
  layer_data["layer_name"],
594
594
  pad_type,
595
595
  pad_shape,
596
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))),
597
+ self._ppadstack._pedb.edb_value(layer_data.get("offset_x", 0)),
598
+ self._ppadstack._pedb.edb_value(layer_data.get("offset_y", 0)),
599
+ self._ppadstack._pedb.edb_value(layer_data.get("rotation", 0)),
600
600
  )
601
601
  self._padstack_def_data = pdef_data
602
602
 
@@ -2324,3 +2324,15 @@ class EDBPadstackInstance(Primitive):
2324
2324
  max_limit=max_limit,
2325
2325
  component_only=component_only,
2326
2326
  )
2327
+
2328
+ @property
2329
+ def properties(self):
2330
+ data = {}
2331
+ data["name"] = self.aedt_name
2332
+ data["definition"] = self.padstack_definition
2333
+ data["backdrill_parameters"] = self.backdrill_parameters
2334
+ _, position, rotation = self._edb_object.GetPositionAndRotationValue()
2335
+ data["position"] = [position.X.ToString(), position.Y.ToString()]
2336
+ data["rotation"] = [rotation.ToString()]
2337
+ data["id"] = self.id
2338
+ return data
@@ -22,6 +22,7 @@
22
22
 
23
23
  import re
24
24
 
25
+ from pyedb.dotnet.clr_module import String
25
26
  from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
26
27
  from pyedb.dotnet.edb_core.edb_data.primitives_data import Primitive
27
28
  from pyedb.generic.general_methods import generate_unique_name
@@ -168,7 +169,7 @@ class LayoutValidation:
168
169
  _objects_list[n_name].append(prim)
169
170
  else:
170
171
  _objects_list[n_name] = [prim]
171
- for pad in list(self._pedb.padstacks.instances.values()):
172
+ for pad in list(self._pedb.layout.padstack_instances):
172
173
  n_name = pad.net_name
173
174
  if n_name in _padstacks_list:
174
175
  _padstacks_list[n_name].append(pad)
@@ -318,3 +319,25 @@ class LayoutValidation:
318
319
 
319
320
  self._pedb._logger.info("Found {} inductors have no value.".format(len(temp)))
320
321
  return
322
+
323
+ def padstacks_no_name(self, fix=False):
324
+ pds = self._pedb.layout.padstack_instances
325
+ counts = 0
326
+ via_count = 1
327
+ for obj in pds:
328
+ val = String("")
329
+ _, name = obj._edb_object.GetProductProperty(self._pedb.edb_api.ProductId.Designer, 11, val)
330
+ name = str(name).strip("'")
331
+ if name == "":
332
+ counts += 1
333
+ if fix:
334
+ if not obj.component:
335
+ obj._edb_object.SetProductProperty(
336
+ self._pedb.edb_api.ProductId.Designer, 11, f"via_{via_count}"
337
+ )
338
+ via_count = via_count + 1
339
+ else:
340
+ obj._edb_object.SetProductProperty(
341
+ self._pedb.edb_api.ProductId.Designer, 11, f"{obj.component.name}-{obj.component_pin}"
342
+ )
343
+ self._pedb._logger.info(f"Found {counts}/{len(pds)} padstacks have no name.")
@@ -220,7 +220,6 @@ class EdbPadstacks(object):
220
220
  List of padstack instances.
221
221
 
222
222
  """
223
-
224
223
  edb_padstack_inst_list = self._pedb.layout.padstack_instances
225
224
  if len(self._instances) == len(edb_padstack_inst_list):
226
225
  return self._instances
pyedb/siwave.py CHANGED
@@ -555,13 +555,15 @@ class Siwave(object): # pragma no cover
555
555
  self.import_edb(temp_edb)
556
556
  shutil.rmtree(Path(temp_edb), ignore_errors=True)
557
557
 
558
- def export_configuration(self, file_path: str):
558
+ def export_configuration(self, file_path: str, fix_padstack_names: bool = False):
559
559
  """Export layout information into a configuration file.
560
560
 
561
561
  Parameters
562
562
  ----------
563
563
  file_path : str
564
564
  Path to the configuration file.
565
+ fix_padstack_names : bool
566
+ Name all the padstacks in edb.
565
567
  """
566
568
  file_path = parser_file_path(file_path)
567
569
 
@@ -570,5 +572,7 @@ class Siwave(object): # pragma no cover
570
572
 
571
573
  self.export_edb(temp_edb)
572
574
  edbapp = Edb(temp_edb, edbversion=self.current_version)
575
+ if fix_padstack_names:
576
+ edbapp.layout_validation.padstacks_no_name(fix=True)
573
577
  edbapp.configuration.export(file_path)
574
578
  edbapp.close()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyedb
3
- Version: 0.29.0
3
+ Version: 0.30.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>
@@ -27,7 +27,7 @@ Requires-Dist: toml == 0.10.2
27
27
  Requires-Dist: scikit-rf
28
28
  Requires-Dist: ansys-sphinx-theme>=0.10.0,<1.1 ; extra == "doc"
29
29
  Requires-Dist: imageio>=2.30.0,<2.36 ; extra == "doc"
30
- Requires-Dist: ipython>=8.13.0,<8.28 ; extra == "doc"
30
+ Requires-Dist: ipython>=8.13.0,<8.29 ; extra == "doc"
31
31
  Requires-Dist: jupyterlab>=4.0.0,<4.3 ; extra == "doc"
32
32
  Requires-Dist: jupytext>=1.16.0,<1.17 ; extra == "doc"
33
33
  Requires-Dist: matplotlib>=3.5.0,<3.10 ; extra == "doc"
@@ -38,7 +38,7 @@ 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
40
  Requires-Dist: sphinx-autobuild==2021.3.14 ; extra == "doc" and ( python_version == '3.8')
41
- Requires-Dist: sphinx-autobuild==2024.9.19 ; extra == "doc" and ( python_version > '3.8')
41
+ Requires-Dist: sphinx-autobuild==2024.10.3 ; extra == "doc" and ( python_version > '3.8')
42
42
  Requires-Dist: sphinx-copybutton>=0.5.0,<0.6 ; extra == "doc"
43
43
  Requires-Dist: sphinx-gallery>=0.14.0,<0.18 ; extra == "doc"
44
44
  Requires-Dist: sphinx_design>=0.4.0,<0.7 ; extra == "doc"
@@ -1,51 +1,51 @@
1
- pyedb/__init__.py,sha256=COiSZ1vj_2OSaMqSgyfOmdERHaQq_6eGg-pLRyxvazs,1521
1
+ pyedb/__init__.py,sha256=i3nK0Ify0Hxn6Qa-eIDag4HU7ru7gjzKnxiqqamC3KM,2592
2
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=6SL3PnklGMbVOsstvJJ1fx3D3YkBWr27pYDUG-U4VB8,17520
4
+ pyedb/siwave.py,sha256=Mgg5ZGzOUOtNdlePHcnrgN3rletQ7jrqRi3WfxF58uU,17727
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=5_v6HD0VgkFCJHgx5zTIn_nxPv3KpcCuGz9P4Kk4ywM,6246
9
9
  pyedb/configuration/cfg_common.py,sha256=yF_dwdHA8rsyBcqLmhfkJoZ_aOVkDM5pqePGQqBh-Nk,1992
10
- pyedb/configuration/cfg_components.py,sha256=qsIsrvFrCNg_HEX9bup7L_-y1tQTwVJSd_1QFsEyxxk,4592
11
- pyedb/configuration/cfg_data.py,sha256=SUweTdyowk7wpi6eGBkBOkVvvcYNZOjf2_6pKjwtJns,3494
12
- pyedb/configuration/cfg_general.py,sha256=0dtd-rkQt2aYR3EOL0c3sNuDuJs7htRos1OWck3rxaI,1626
10
+ pyedb/configuration/cfg_components.py,sha256=-AXoHvFqrQI_j6JCzXPit-u6cYK-qR2_k1msPrn_Xkw,4587
11
+ pyedb/configuration/cfg_data.py,sha256=KPejkIgaY1JfLA8gsbsqcn1x9gEgyDMok1A33sgXHGs,3498
12
+ pyedb/configuration/cfg_general.py,sha256=DJAKTW8Sqojfqzc3jO3MU1-J8MrmVi37jUIkTD_Tw6o,2068
13
13
  pyedb/configuration/cfg_nets.py,sha256=18NezeNh0ZOwk2ehz3zWJF_xYR7IYCqGlpDfDt7Ilho,2349
14
14
  pyedb/configuration/cfg_operations.py,sha256=mk0uY9kWEZ6hLciZz6l9ESBC-yHr08GgWBEX2iLutPE,4674
15
15
  pyedb/configuration/cfg_package_definition.py,sha256=f_RRT9R-3H5kHBlc4QSpjq9uQgYbaKQ78XXXrc_r3kg,5296
16
- pyedb/configuration/cfg_padstacks.py,sha256=qnxhdqGs5xHRW0luzkNpj8yB3zO8zuD4XZgP1PDxrOk,4428
16
+ pyedb/configuration/cfg_padstacks.py,sha256=GNastAjgvqf90IxNZTbsMI_x9fQx5_FLbIsNqZ2ChNI,4766
17
17
  pyedb/configuration/cfg_pin_groups.py,sha256=b0H6NaPKJ5zlcXL9W2Q8_HbiLB8-OxaqjsM4wlqP2ic,3768
18
18
  pyedb/configuration/cfg_ports_sources.py,sha256=8D4QcHlrCdMI0URv3NzSRf0ke8BiF1dpREiimwb9Hbk,16430
19
19
  pyedb/configuration/cfg_s_parameter_models.py,sha256=iwLT581u7v26QtsLOaxrtpvAxrnk1VWqNiRYKOmK3y0,5300
20
- pyedb/configuration/cfg_setup.py,sha256=SPpNRLJusB-Cz2fDQkc6gkdilUqIlbNngoxF3zySt6g,10115
20
+ pyedb/configuration/cfg_setup.py,sha256=QGKQHAEeo196TYtKMvIMb2-p8KC4U8fmHx0yn0SpgMo,10351
21
21
  pyedb/configuration/cfg_spice_models.py,sha256=Q_5j2-V6cepSFcnijot8iypTqzanLp7HOz-agmnwKns,2570
22
- pyedb/configuration/cfg_stackup.py,sha256=CX7uNN5QRoYW_MOObknP8003YchTS7PH9Oee7FG0VKU,6589
23
- pyedb/configuration/configuration.py,sha256=vuoCHQ254tpA5sHrK1Muhq5ghaZhn_Sh4Q7F-8EvxoM,14307
22
+ pyedb/configuration/cfg_stackup.py,sha256=ZKUcTh4UAFLJgES2W-5J7uXkUdz_q0URg28lUZUyfdo,6433
23
+ pyedb/configuration/configuration.py,sha256=ndNU2C9Kgp7t2InZt0IcrBXooxjwFChpc7ylajhbTNc,14622
24
24
  pyedb/dotnet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  pyedb/dotnet/clr_module.py,sha256=Mo13Of3DVSA5HR-5xZEXOiHApIKy52CUxtJ2gPkEu1A,3406
26
- pyedb/dotnet/edb.py,sha256=FtDiXt8AY0azMVvhp-l9HEDde1-goGCxXAcafwhKki4,182283
26
+ pyedb/dotnet/edb.py,sha256=He8yGP0ykTRCmiHZMDGQvT5Eeg-m0t9-HLbRquBLu2Y,184294
27
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
- pyedb/dotnet/edb_core/components.py,sha256=g2hPrTotCtHWA7y79ej1fw3UoY5KrgDwur3H3m-Vmfg,111194
30
+ pyedb/dotnet/edb_core/components.py,sha256=r8Gr9mV4Cuky7lVKOg-JWhRR2bflGYESsnOGG2g4BwM,111146
31
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
- pyedb/dotnet/edb_core/layout_validation.py,sha256=JLWPZiSkjopAPLksysB1X6fbc5KBfD4_RViOeu7ABoE,12612
34
+ pyedb/dotnet/edb_core/layout_validation.py,sha256=ONhxkMFi9k5Or_F4l4pdOzyj1-ZVKE2BmbgxbuvCOHE,13647
35
35
  pyedb/dotnet/edb_core/materials.py,sha256=zzYWIJ5dvOIO2H2vREpRnwGDx0hEa5QhCsg_EJkydww,43222
36
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=kD8Pa4JCon6ZOS2H3B9B32m24qNBZQDA69_m2zKlVa4,41464
39
- pyedb/dotnet/edb_core/padstack.py,sha256=P4WqnMy_mRHHPNvLCG96eGGB8_8bSZPBVziStxGNd5I,63567
39
+ pyedb/dotnet/edb_core/padstack.py,sha256=19cRYqTHVjjvblYVoZgMetRBXDjtP5-URUv6eA0mvfY,63566
40
40
  pyedb/dotnet/edb_core/siwave.py,sha256=4duoAsFCuPMNLxtMTEEVJCUaHKNkdbLDmtTXiD93VrM,64311
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=1BZ5j5sD7cuomG3-mV7Z7UBtfko39m6xm6Fjgwvn0zo,12696
44
+ pyedb/dotnet/edb_core/cell/layout.py,sha256=qMok2j0LbjoYJ0QBDEZp-nHDLaIXZYZ1jPpqso7z5gs,12448
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
48
- pyedb/dotnet/edb_core/cell/hierarchy/component.py,sha256=w3K3ofIH8xF9-8L_Rqc6uNk6O6WHR5b5zeVEk3d1L38,43508
48
+ pyedb/dotnet/edb_core/cell/hierarchy/component.py,sha256=3TlxpkCIJnAC13xEzzm65ar43AaC9CFE_pskb79yHHQ,43673
49
49
  pyedb/dotnet/edb_core/cell/hierarchy/hierarchy_obj.py,sha256=OUNK6INKlbJkCbzy6jKZzrQs7fvCR1qiTjt7te0S7nQ,2160
50
50
  pyedb/dotnet/edb_core/cell/hierarchy/model.py,sha256=LwXE4VUfptG5rJ9gmAmye0hECBv7bUGtby1ZzNFkeT0,3198
51
51
  pyedb/dotnet/edb_core/cell/hierarchy/netlist_model.py,sha256=fF6tY-6s-lW9EuvJ5sw3RlIkjuoSjeZbrNk5wG-_hzM,1356
@@ -55,7 +55,7 @@ pyedb/dotnet/edb_core/cell/hierarchy/spice_model.py,sha256=SGiUcan2l0n8DGk3GtwCs
55
55
  pyedb/dotnet/edb_core/cell/primitive/__init__.py,sha256=8jByHkoaowAYQTCww-zRrTQmN061fLz_OHjTLSrzQQY,58
56
56
  pyedb/dotnet/edb_core/cell/primitive/bondwire.py,sha256=fqIMdv0bNvk591DG6De5c--w9Rpkl5AOeo_qgzoPE6M,7322
57
57
  pyedb/dotnet/edb_core/cell/primitive/path.py,sha256=XVN7dOVpccoBP28M8l5iMzK5QSQdHqpKqC4jK76UTis,12543
58
- pyedb/dotnet/edb_core/cell/primitive/primitive.py,sha256=o4qmw_-egaV2QCUQe7EEq4O1a5G5hZnACGTj_ET1MQ0,27605
58
+ pyedb/dotnet/edb_core/cell/primitive/primitive.py,sha256=ApzSvcKHs3UI8hOOSqT3mTDAgjXfGCSMw01QFey7ohY,27675
59
59
  pyedb/dotnet/edb_core/cell/terminal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
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
@@ -77,9 +77,9 @@ pyedb/dotnet/edb_core/edb_data/control_file.py,sha256=_W5DDBFvm4gTq8yCvhzfiWUsfp
77
77
  pyedb/dotnet/edb_core/edb_data/design_options.py,sha256=RO9ip-T5Bfxpsl97_QEk0qDZsza3tLzIX2t25XLutys,2057
78
78
  pyedb/dotnet/edb_core/edb_data/edbvalue.py,sha256=Vj_11HXsQUNavizKp5FicORm6cjhXRh9uvxhv_D_RJc,1977
79
79
  pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py,sha256=wIKH4it1uYkEae4OimS3YE6QoSf8rAAIhxdTwtR9cqU,13040
80
- pyedb/dotnet/edb_core/edb_data/layer_data.py,sha256=2K1rvBXAWg3s8paNU6TPNb5tC1B3bRHmiUZjVsoX_Z8,26001
80
+ pyedb/dotnet/edb_core/edb_data/layer_data.py,sha256=Yg3y80d4dn47vtFaNUr2Mt8LRIKvu9TMGxQiu9CIc_s,29586
81
81
  pyedb/dotnet/edb_core/edb_data/nets_data.py,sha256=B3SirURVYrmFZPjQLGEYUfTSDZOzzCSB1l7CPQFdWr4,9942
82
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py,sha256=Hav6QucvfsqnBv-VjPMEXA4AFq5F5Lf3UVRfdxzbTXk,87476
82
+ pyedb/dotnet/edb_core/edb_data/padstacks_data.py,sha256=QACrVhAiVbu8GASxrynqmVrDHZCEpm5wvgSg5EO3t5Q,87918
83
83
  pyedb/dotnet/edb_core/edb_data/ports.py,sha256=wr2RQi8VExuNIVmnp7c4VpTIhODgthmJmHr01zO4ueo,8873
84
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
@@ -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.29.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
189
- pyedb-0.29.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
190
- pyedb-0.29.0.dist-info/METADATA,sha256=v1FkL09xH_fMTtmrbe3D6kJ5aBxzYG7fW_MoFuChYrQ,8389
191
- pyedb-0.29.0.dist-info/RECORD,,
188
+ pyedb-0.30.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
189
+ pyedb-0.30.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
190
+ pyedb-0.30.0.dist-info/METADATA,sha256=-lDcxg_ntc5YBawrtVWPdjn7L3k6jWTlI9U-jMGlUzc,8389
191
+ pyedb-0.30.0.dist-info/RECORD,,
File without changes