pyedb 0.7.0__py3-none-any.whl → 0.8.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 (46) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/dotnet/clr_module.py +1 -1
  3. pyedb/dotnet/edb.py +7 -7
  4. pyedb/dotnet/edb_core/cell/hierarchy/model.py +1 -1
  5. pyedb/dotnet/edb_core/components.py +15 -12
  6. pyedb/dotnet/edb_core/configuration.py +232 -25
  7. pyedb/dotnet/edb_core/definition/component_def.py +10 -1
  8. pyedb/dotnet/edb_core/definition/component_model.py +1 -1
  9. pyedb/dotnet/edb_core/definition/definition_obj.py +1 -1
  10. pyedb/dotnet/edb_core/definition/definitions.py +8 -2
  11. pyedb/dotnet/edb_core/definition/package_def.py +61 -15
  12. pyedb/dotnet/edb_core/dotnet/database.py +5 -4
  13. pyedb/dotnet/edb_core/edb_data/components_data.py +3 -2
  14. pyedb/dotnet/edb_core/edb_data/connectable.py +1 -1
  15. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +14 -13
  16. pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +2 -2
  17. pyedb/dotnet/edb_core/edb_data/layer_data.py +9 -3
  18. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +6 -5
  19. pyedb/dotnet/edb_core/edb_data/primitives_data.py +16 -13
  20. pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +7 -1
  21. pyedb/dotnet/edb_core/edb_data/sources.py +10 -0
  22. pyedb/dotnet/edb_core/geometry/__init__.py +0 -0
  23. pyedb/dotnet/edb_core/{edb_data/obj_base.py → geometry/point_data.py} +12 -26
  24. pyedb/dotnet/edb_core/geometry/polygon_data.py +77 -0
  25. pyedb/dotnet/edb_core/layout.py +59 -0
  26. pyedb/dotnet/edb_core/materials.py +715 -597
  27. pyedb/dotnet/edb_core/nets.py +3 -3
  28. pyedb/dotnet/edb_core/obj_base.py +94 -0
  29. pyedb/dotnet/edb_core/padstack.py +57 -6
  30. pyedb/dotnet/edb_core/siwave.py +11 -4
  31. pyedb/dotnet/edb_core/stackup.py +152 -131
  32. pyedb/dotnet/edb_core/utilities/__init__.py +3 -0
  33. pyedb/dotnet/edb_core/utilities/heatsink.py +69 -0
  34. pyedb/dotnet/sim_setup_data/data/siw_dc_ir_settings.py +46 -0
  35. pyedb/edb_logger.py +15 -1
  36. pyedb/exceptions.py +6 -0
  37. pyedb/generic/filesystem.py +7 -3
  38. pyedb/generic/general_methods.py +4 -0
  39. pyedb/generic/process.py +4 -1
  40. pyedb/generic/settings.py +30 -8
  41. pyedb/siwave.py +50 -1
  42. {pyedb-0.7.0.dist-info → pyedb-0.8.0.dist-info}/METADATA +31 -53
  43. {pyedb-0.7.0.dist-info → pyedb-0.8.0.dist-info}/RECORD +46 -39
  44. /pyedb/dotnet/edb_core/{edb_data → utilities}/simulation_setup.py +0 -0
  45. {pyedb-0.7.0.dist-info → pyedb-0.8.0.dist-info}/LICENSE +0 -0
  46. {pyedb-0.7.0.dist-info → pyedb-0.8.0.dist-info}/WHEEL +0 -0
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.7.0"
47
+ __version__ = "0.8.0"
48
48
  version = __version__
49
49
 
50
50
  #
@@ -83,7 +83,7 @@ except ImportError: # pragma: no cover
83
83
  )
84
84
  edb_initialized = False
85
85
  elif sys.version[0] == 3 and sys.version[1] < 7:
86
- warnings.warn("EDB requires Linux Python 3.7 or later.")
86
+ warnings.warn("EDB requires Linux Python 3.8 or later.")
87
87
  _clr = None
88
88
  String = None
89
89
  Double = None
pyedb/dotnet/edb.py CHANGED
@@ -848,12 +848,11 @@ class Edb(Database):
848
848
  Examples
849
849
  --------
850
850
  >>> from pyedb.dotnet.edb import Edb
851
- >>> edbapp = Edb("myproject.aedb")
852
- >>> edbapp.materials["FR4_epoxy"].conductivity = 1
853
- >>> edbapp.materials.add_debye_material("My_Debye2", 5, 3, 0.02, 0.05, 1e5, 1e9)
854
- >>> edbapp.materials.add_djordjevicsarkar_material("MyDjord2", 3.3, 0.02, 3.3)
851
+ >>> edbapp = Edb()
852
+ >>> edbapp.materials.add_material("air", permittivity=1.0)
853
+ >>> edbapp.materials.add_debye_material("debye_mat", 5, 3, 0.02, 0.05, 1e5, 1e9)
854
+ >>> edbapp.materials.add_djordjevicsarkar_material("djord_mat", 3.3, 0.02, 3.3)
855
855
  """
856
-
857
856
  if not self._materials and self.active_db:
858
857
  self._materials = Materials(self)
859
858
  return self._materials
@@ -3638,6 +3637,7 @@ class Edb(Database):
3638
3637
  >>> setup1.hfss_port_settings.max_delta_z0 = 0.5
3639
3638
  """
3640
3639
  if name in self.setups:
3640
+ self.logger.info("setup already exists")
3641
3641
  return False
3642
3642
  setup = HfssSimulationSetup(self).create(name)
3643
3643
  return setup
@@ -4142,8 +4142,8 @@ class Edb(Database):
4142
4142
  loss_tg_variable = "$loss_tangent_{}".format(mat_name)
4143
4143
  loss_tg_variable = self._clean_string_for_variable_name(loss_tg_variable)
4144
4144
  if not loss_tg_variable in self.variables:
4145
- self.add_design_variable(loss_tg_variable, material.loss_tangent)
4146
- material.loss_tangent = loss_tg_variable
4145
+ self.add_design_variable(loss_tg_variable, material.dielectric_loss_tangent)
4146
+ material.dielectric_loss_tangent = loss_tg_variable
4147
4147
  parameters.append(loss_tg_variable)
4148
4148
  else:
4149
4149
  sigma_variable = "$sigma_{}".format(mat_name)
@@ -20,7 +20,7 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
23
+ from pyedb.dotnet.edb_core.obj_base import ObjBase
24
24
  from pyedb.generic.general_methods import pyedb_function_handler
25
25
 
26
26
 
@@ -38,6 +38,7 @@ from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
38
38
  from pyedb.dotnet.edb_core.padstack import EdbPadstacks
39
39
  from pyedb.generic.general_methods import (
40
40
  _retry_ntimes,
41
+ generate_unique_name,
41
42
  get_filename_without_extension,
42
43
  pyedb_function_handler,
43
44
  )
@@ -1408,7 +1409,7 @@ class Components(object):
1408
1409
 
1409
1410
  @pyedb_function_handler()
1410
1411
  def create_rlc_component(
1411
- self, pins, component_name="", r_value=1.0, c_value=1e-9, l_value=1e-9, is_parallel=False
1412
+ self, pins, component_name="", r_value=None, c_value=None, l_value=None, is_parallel=False
1412
1413
  ): # pragma: no cover
1413
1414
  """Create physical Rlc component.
1414
1415
 
@@ -1450,13 +1451,13 @@ class Components(object):
1450
1451
  def create(
1451
1452
  self,
1452
1453
  pins,
1453
- component_name,
1454
+ component_name=None,
1454
1455
  placement_layer=None,
1455
1456
  component_part_name=None,
1456
1457
  is_rlc=False,
1457
- r_value=0,
1458
- c_value=0,
1459
- l_value=0,
1458
+ r_value=None,
1459
+ c_value=None,
1460
+ l_value=None,
1460
1461
  is_parallel=False,
1461
1462
  ):
1462
1463
  """Create a component from pins.
@@ -1496,6 +1497,8 @@ class Components(object):
1496
1497
  >>> edbapp.components.create(pins, "A1New")
1497
1498
 
1498
1499
  """
1500
+ if not component_name:
1501
+ component_name = generate_unique_name("Comp_")
1499
1502
  if component_part_name:
1500
1503
  compdef = self._getComponentDefinition(component_part_name, pins)
1501
1504
  else:
@@ -1523,21 +1526,21 @@ class Components(object):
1523
1526
  if is_rlc and len(pins) == 2:
1524
1527
  rlc = self._edb.utility.utility.Rlc()
1525
1528
  rlc.IsParallel = is_parallel
1526
- if r_value:
1529
+ if r_value is None:
1530
+ rlc.REnabled = False
1531
+ else:
1527
1532
  rlc.REnabled = True
1528
1533
  rlc.R = self._get_edb_value(r_value)
1534
+ if l_value is None:
1535
+ rlc.LEnabled = False
1529
1536
  else:
1530
- rlc.REnabled = False
1531
- if l_value:
1532
1537
  rlc.LEnabled = True
1533
1538
  rlc.L = self._get_edb_value(l_value)
1539
+ if c_value is None:
1540
+ rlc.CEnabled = False
1534
1541
  else:
1535
- rlc.LEnabled = False
1536
- if c_value:
1537
1542
  rlc.CEnabled = True
1538
1543
  rlc.C = self._get_edb_value(c_value)
1539
- else:
1540
- rlc.CEnabled = False
1541
1544
  if rlc.REnabled and not rlc.CEnabled and not rlc.CEnabled:
1542
1545
  new_cmp.SetComponentType(self._edb.definition.ComponentType.Resistor)
1543
1546
  elif rlc.CEnabled and not rlc.REnabled and not rlc.LEnabled:
@@ -21,17 +21,13 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  import json
24
+ import os
24
25
  from pathlib import Path
25
26
 
26
- from pyedb.generic.general_methods import pyedb_function_handler
27
-
27
+ import toml
28
28
 
29
- def load_json(config_file):
30
- if isinstance(config_file, (str, Path)):
31
- with open(config_file, "r") as f:
32
- return json.load(f)
33
- elif isinstance(config_file, dict):
34
- return config_file
29
+ from pyedb.dotnet.edb_core.definition.package_def import PackageDef
30
+ from pyedb.generic.general_methods import pyedb_function_handler
35
31
 
36
32
 
37
33
  class Configuration:
@@ -46,12 +42,12 @@ class Configuration:
46
42
 
47
43
  @pyedb_function_handler
48
44
  def load(self, config_file, append=True, apply_file=False, output_file=None, open_at_the_end=True):
49
- """Import configuration settings from a JSON file.
45
+ """Import configuration settings from a configure file.
50
46
 
51
47
  Parameters
52
48
  ----------
53
- config_file : str
54
- Full path to json file.
49
+ config_file : str, dict
50
+ Full path to configure file in JSON or TOML format. Dictionary is also supported.
55
51
  append : bool, optional
56
52
  Whether if the new file will append to existing properties or the properties will be cleared before import.
57
53
  Default is ``True`` to keep stored properties
@@ -67,12 +63,29 @@ class Configuration:
67
63
  dict
68
64
  Config dictionary.
69
65
  """
66
+ if isinstance(config_file, dict):
67
+ data = config_file
68
+ elif os.path.isfile(config_file):
69
+ with open(config_file, "r") as f:
70
+ if config_file.endswith(".json"):
71
+ data = json.load(f)
72
+ elif config_file.endswith(".toml"):
73
+ data = toml.load(f)
74
+ else: # pragma: no cover
75
+ return False
70
76
 
71
- data = load_json(config_file)
72
- if not append:
77
+ if not append: # pragma: no cover
73
78
  self.data = {}
74
79
  for k, v in data.items():
75
- self.data[k] = v
80
+ if k in self.data:
81
+ if isinstance(v, list):
82
+ self.data[k].extend(v)
83
+ elif isinstance(v, dict): # pragma: no cover
84
+ self.data[k].update(v)
85
+ else: # pragma: no cover
86
+ self.data[k] = v
87
+ else:
88
+ self.data[k] = v
76
89
  if apply_file:
77
90
  original_file = self._pedb.edbpath
78
91
  if output_file:
@@ -98,6 +111,10 @@ class Configuration:
98
111
  if "general" in self.data:
99
112
  self._load_general()
100
113
 
114
+ # Configure boundary settings
115
+ if "boundaries" in self.data:
116
+ self._load_boundaries()
117
+
101
118
  # Configure nets
102
119
  if "nets" in self.data:
103
120
  self._load_nets()
@@ -106,6 +123,10 @@ class Configuration:
106
123
  if "components" in self.data:
107
124
  self._load_components()
108
125
 
126
+ # Configure padstacks
127
+ if "padstacks" in self.data:
128
+ self._load_padstacks()
129
+
109
130
  # Configure pin groups
110
131
  if "pin_groups" in self.data:
111
132
  self._load_pin_groups()
@@ -134,6 +155,14 @@ class Configuration:
134
155
  if "spice_models" in self.data:
135
156
  self._load_spice_models()
136
157
 
158
+ # Configure package definitions
159
+ if "package_definitions" in self.data:
160
+ self._load_package_def()
161
+
162
+ # Configure operations
163
+ if "operations" in self.data:
164
+ self._load_operations()
165
+
137
166
  return True
138
167
 
139
168
  @pyedb_function_handler
@@ -253,18 +282,20 @@ class Configuration:
253
282
  pos_terminal = ""
254
283
  if "pin_group" in positive_terminal_json:
255
284
  pin_group = self._pedb.siwave.pin_groups[positive_terminal_json["pin_group"]]
256
- pos_terminal = pin_group.get_terminal(pin_group.name, True)
285
+ port_name = pin_group.name if "name" not in port else port["name"]
286
+ pos_terminal = pin_group.get_terminal(port_name, True)
287
+
257
288
  else:
258
289
  ref_designator = port["reference_designator"]
259
290
  comp_layout = self._components[ref_designator]
260
291
 
261
292
  if "pin" in positive_terminal_json:
262
293
  pin_name = positive_terminal_json["pin"]
263
- port_name = "{}_{}".format(ref_designator, pin_name)
294
+ port_name = "{}_{}".format(ref_designator, pin_name) if "name" not in port else port["name"]
264
295
  pos_terminal = comp_layout.pins[pin_name].get_terminal(port_name, True)
265
296
  else: # Net
266
297
  net_name = positive_terminal_json["net"]
267
- port_name = "{}_{}".format(ref_designator, net_name)
298
+ port_name = "{}_{}".format(ref_designator, net_name) if "name" not in port else port["name"]
268
299
  if port_type == "circuit":
269
300
  pg_name = "pg_{}".format(port_name)
270
301
  _, pg = self._pedb.siwave.create_pin_group_on_net(ref_designator, net_name, pg_name)
@@ -352,6 +383,7 @@ class Configuration:
352
383
  elif src_type == "current":
353
384
  src_obj = self._pedb.create_current_source(pos_terminal, neg_terminal)
354
385
  src_obj.magnitude = src["magnitude"]
386
+ src_obj.name = name
355
387
 
356
388
  @pyedb_function_handler
357
389
  def _load_setups(self):
@@ -370,6 +402,13 @@ class Configuration:
370
402
  self._pedb.logger.warning("Setup {} already existing. Editing it.".format(name))
371
403
  edb_setup = self._pedb.setups[name]
372
404
  edb_setup.set_dc_slider(setup["dc_slider_position"])
405
+ dc_ir_settings = setup.get("dc_ir_settings", None)
406
+ if dc_ir_settings:
407
+ for k, v in dc_ir_settings.items():
408
+ if k not in dir(edb_setup.dc_ir_settings):
409
+ self._pedb.logger.error(f"Invalid keyword {k}")
410
+ else:
411
+ setattr(edb_setup.dc_ir_settings, k, v)
373
412
  else:
374
413
  if setup_type.lower() == "hfss":
375
414
  if name not in self._pedb.setups:
@@ -389,7 +428,10 @@ class Configuration:
389
428
  else:
390
429
  self._pedb.logger.warning("Setup {} already existing. Editing it.".format(name))
391
430
  edb_setup = self._pedb.setups[name]
392
- edb_setup.si_slider_position = setup["si_slider_position"]
431
+ if "si_slider_position" in setup:
432
+ edb_setup.si_slider_position = setup["si_slider_position"]
433
+ if "pi_slider_position" in setup:
434
+ edb_setup.pi_slider_position = setup["pi_slider_position"]
393
435
 
394
436
  if "freq_sweep" in setup:
395
437
  for fsweep in setup["freq_sweep"]:
@@ -476,14 +518,23 @@ class Configuration:
476
518
  comp_def_name = sp["component_definition"]
477
519
  comp_def = self._pedb.definitions.component[comp_def_name]
478
520
  comp_def.add_n_port_model(fpath, sp_name)
521
+ comp_list = dict()
479
522
  if sp["apply_to_all"]:
480
- for refdes, comp in comp_def.components.items():
481
- if refdes not in sp["components"]:
482
- comp.use_s_parameter_model(sp_name)
523
+ comp_list.update(
524
+ {refdes: comp for refdes, comp in comp_def.components.items() if refdes not in sp["components"]}
525
+ )
483
526
  else:
484
- for refdes, comp in comp_def.components.items():
485
- if refdes in sp["components"]:
486
- comp.use_s_parameter_model(sp_name)
527
+ comp_list.update(
528
+ {refdes: comp for refdes, comp in comp_def.components.items() if refdes in sp["components"]}
529
+ )
530
+
531
+ for refdes, comp in comp_list.items():
532
+ if "reference_net_per_component" in sp:
533
+ ref_net_per_comp = sp["reference_net_per_component"]
534
+ ref_net = ref_net_per_comp[refdes] if refdes in ref_net_per_comp else sp["reference_net"]
535
+ else:
536
+ ref_net = sp["reference_net"]
537
+ comp.use_s_parameter_model(sp_name, reference_net=ref_net)
487
538
 
488
539
  @pyedb_function_handler
489
540
  def _load_spice_models(self):
@@ -510,13 +561,21 @@ class Configuration:
510
561
  @pyedb_function_handler
511
562
  def _load_pin_groups(self):
512
563
  """Imports pin groups information from JSON."""
564
+ comps = self._pedb.components.components
513
565
  for pg in self.data["pin_groups"]:
514
566
  name = pg["name"]
515
567
  ref_designator = pg["reference_designator"]
516
568
  if "pins" in pg:
517
569
  self._pedb.siwave.create_pin_group(ref_designator, pg["pins"], name)
518
570
  elif "net" in pg:
519
- self._pedb.siwave.create_pin_group_on_net(ref_designator, pg["net"], name)
571
+ nets = pg["net"]
572
+ nets = nets if isinstance(nets, list) else [nets]
573
+ comp = comps[ref_designator]
574
+ pins = [p for p, obj in comp.pins.items() if obj.net_name in nets]
575
+ self._pedb.siwave.create_pin_group(ref_designator, pins, name)
576
+ else:
577
+ pins = [i for i in comps[ref_designator].pins.keys()]
578
+ self._pedb.siwave.create_pin_group(ref_designator, pins, name)
520
579
 
521
580
  @pyedb_function_handler
522
581
  def _load_nets(self):
@@ -536,3 +595,151 @@ class Configuration:
536
595
  self._s_parameter_library = general["s_parameter_library"]
537
596
  if "spice_model_library" in general:
538
597
  self._spice_model_library = general["spice_model_library"]
598
+
599
+ @pyedb_function_handler
600
+ def _load_boundaries(self):
601
+ """Imports boundary information from JSON."""
602
+ boundaries = self.data["boundaries"]
603
+
604
+ open_region = boundaries.get("open_region", None)
605
+ if open_region:
606
+ self._pedb.hfss.hfss_extent_info.use_open_region = open_region
607
+
608
+ open_region_type = boundaries.get("open_region_type", None)
609
+ if open_region_type:
610
+ self._pedb.hfss.hfss_extent_info.open_region_type = open_region_type
611
+
612
+ pml_visible = boundaries.get("pml_visible", None)
613
+ if pml_visible:
614
+ self._pedb.hfss.hfss_extent_info.is_pml_visible = pml_visible
615
+
616
+ pml_operation_frequency = boundaries.get("pml_operation_frequency", None)
617
+ if pml_operation_frequency:
618
+ self._pedb.hfss.hfss_extent_info.operating_freq = pml_operation_frequency
619
+
620
+ pml_radiation_factor = boundaries.get("pml_radiation_factor", None)
621
+ if pml_radiation_factor:
622
+ self._pedb.hfss.hfss_extent_info.radiation_level = pml_radiation_factor
623
+
624
+ dielectric_extents_type = boundaries.get("dielectric_extents_type", None)
625
+ if dielectric_extents_type:
626
+ self._pedb.hfss.hfss_extent_info.extent_type = dielectric_extents_type
627
+
628
+ dielectric_base_polygon = boundaries.get("dielectric_base_polygon", None)
629
+ if dielectric_base_polygon:
630
+ self._pedb.hfss.hfss_extent_info.dielectric_base_polygon = dielectric_base_polygon
631
+
632
+ horizontal_padding = boundaries.get("horizontal_padding", None)
633
+ if horizontal_padding:
634
+ self._pedb.hfss.hfss_extent_info.dielectric_extent_size = horizontal_padding
635
+
636
+ honor_primitives_on_dielectric_layers = boundaries.get("honor_primitives_on_dielectric_layers", None)
637
+ if honor_primitives_on_dielectric_layers:
638
+ self._pedb.hfss.hfss_extent_info.honor_user_dielectric = honor_primitives_on_dielectric_layers
639
+
640
+ air_box_extents_type = boundaries.get("air_box_extents_type", None)
641
+ if air_box_extents_type:
642
+ self._pedb.hfss.hfss_extent_info.extent_type = air_box_extents_type
643
+
644
+ air_box_truncate_model_ground_layers = boundaries.get("air_box_truncate_model_ground_layers", None)
645
+ if air_box_truncate_model_ground_layers:
646
+ self._pedb.hfss.hfss_extent_info.truncate_air_box_at_ground = air_box_truncate_model_ground_layers
647
+
648
+ air_box_horizontal_padding = boundaries.get("air_box_horizontal_padding", None)
649
+ if air_box_horizontal_padding:
650
+ self._pedb.hfss.hfss_extent_info.air_box_horizontal_extent = air_box_horizontal_padding
651
+
652
+ air_box_positive_vertical_padding = boundaries.get("air_box_positive_vertical_padding", None)
653
+ if air_box_positive_vertical_padding:
654
+ self._pedb.hfss.hfss_extent_info.air_box_positive_vertical_extent = air_box_positive_vertical_padding
655
+
656
+ air_box_negative_vertical_padding = boundaries.get("air_box_negative_vertical_padding", None)
657
+ if air_box_positive_vertical_padding:
658
+ self._pedb.hfss.hfss_extent_info.air_box_negative_vertical_extent = air_box_negative_vertical_padding
659
+
660
+ @pyedb_function_handler
661
+ def _load_operations(self):
662
+ """Imports operation information from JSON."""
663
+ operations = self.data["operations"]
664
+ cutout = operations.get("cutout", None)
665
+ if cutout:
666
+ self._pedb.cutout(**cutout)
667
+
668
+ @pyedb_function_handler
669
+ def _load_padstacks(self):
670
+ """Imports padstack information from JSON."""
671
+ padstacks = self.data["padstacks"]
672
+ definitions = padstacks.get("definitions", None)
673
+ if definitions:
674
+ padstack_defs = self._pedb.padstacks.definitions
675
+ for value in definitions:
676
+ pdef = padstack_defs[value["name"]]
677
+ if "hole_diameter" in value:
678
+ pdef.hole_diameter = value["hole_diameter"]
679
+ if "hole_plating_thickness" in value:
680
+ pdef.hole_plating_thickness = value["hole_plating_thickness"]
681
+ if "hole_material" in value:
682
+ pdef.material = value["hole_material"]
683
+ if "hole_range" in value:
684
+ pdef.hole_range = value["hole_range"]
685
+ instances = padstacks.get("instances", None)
686
+ if instances:
687
+ padstack_instances = self._pedb.padstacks.instances_by_name
688
+ for value in instances:
689
+ inst = padstack_instances[value["name"]]
690
+ backdrill_top = value.get("backdrill_top", None)
691
+ if backdrill_top:
692
+ inst.set_backdrill_top(
693
+ backdrill_top["drill_to_layer"], backdrill_top["drill_diameter"], backdrill_top["stub_length"]
694
+ )
695
+ backdrill_bottom = value.get("backdrill_bottom", None)
696
+ if backdrill_top:
697
+ inst.set_backdrill_bottom(
698
+ backdrill_bottom["drill_to_layer"],
699
+ backdrill_bottom["drill_diameter"],
700
+ backdrill_bottom["stub_length"],
701
+ )
702
+
703
+ @pyedb_function_handler
704
+ def _load_package_def(self):
705
+ """Imports package definition information from JSON."""
706
+ comps = self._pedb.components.components
707
+ for pkgd in self.data["package_definitions"]:
708
+ name = pkgd["name"]
709
+ if name in self._pedb.definitions.package:
710
+ self._pedb.definitions.package[name].delete()
711
+ extent_bounding_box = pkgd.get("extent_bounding_box", None)
712
+ if extent_bounding_box:
713
+ package_def = PackageDef(self._pedb, name=name, extent_bounding_box=extent_bounding_box)
714
+ else:
715
+ package_def = PackageDef(self._pedb, name=name, component_part_name=pkgd["component_definition"])
716
+ package_def.maximum_power = pkgd["maximum_power"]
717
+ package_def.therm_cond = pkgd["therm_cond"]
718
+ package_def.theta_jb = pkgd["theta_jb"]
719
+ package_def.theta_jc = pkgd["theta_jc"]
720
+ package_def.height = pkgd["height"]
721
+
722
+ heatsink = pkgd.get("heatsink", None)
723
+ if heatsink:
724
+ package_def.set_heatsink(
725
+ heatsink["fin_base_height"],
726
+ heatsink["fin_height"],
727
+ heatsink["fin_orientation"],
728
+ heatsink["fin_spacing"],
729
+ heatsink["fin_thickness"],
730
+ )
731
+
732
+ comp_def_name = pkgd["component_definition"]
733
+ comp_def = self._pedb.definitions.component[comp_def_name]
734
+
735
+ comp_list = dict()
736
+ if pkgd["apply_to_all"]:
737
+ comp_list.update(
738
+ {refdes: comp for refdes, comp in comp_def.components.items() if refdes not in pkgd["components"]}
739
+ )
740
+ else:
741
+ comp_list.update(
742
+ {refdes: comp for refdes, comp in comp_def.components.items() if refdes in pkgd["components"]}
743
+ )
744
+ for _, i in comp_list.items():
745
+ i.package_def = name
@@ -23,7 +23,7 @@
23
23
  import os
24
24
 
25
25
  from pyedb.dotnet.edb_core.definition.component_model import NPortComponentModel
26
- from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
26
+ from pyedb.dotnet.edb_core.obj_base import ObjBase
27
27
  from pyedb.generic.general_methods import pyedb_function_handler
28
28
 
29
29
 
@@ -152,6 +152,15 @@ class EDBComponentDef(ObjBase):
152
152
  comp.assign_spice_model(file_path, model_name)
153
153
  return True
154
154
 
155
+ @property
156
+ def reference_file(self):
157
+ ref_files = []
158
+ for comp_model in self._comp_model:
159
+ model_type = str(comp_model.GetComponentModelType())
160
+ if model_type == "NPortComponentModel" or model_type == "DynamicLinkComponentModel":
161
+ ref_files.append(comp_model.GetReferenceFile())
162
+ return ref_files
163
+
155
164
  @property
156
165
  def component_models(self):
157
166
  temp = {}
@@ -20,7 +20,7 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
23
+ from pyedb.dotnet.edb_core.obj_base import ObjBase
24
24
  from pyedb.generic.general_methods import pyedb_function_handler
25
25
 
26
26
 
@@ -20,7 +20,7 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
23
+ from pyedb.dotnet.edb_core.obj_base import ObjBase
24
24
 
25
25
 
26
26
  class DefinitionObj(ObjBase):
@@ -40,17 +40,23 @@ class Definitions:
40
40
  return {l.GetName(): PackageDef(self._pedb, l) for l in list(self._pedb.active_db.PackageDefs)}
41
41
 
42
42
  @pyedb_function_handler
43
- def add_package_def(self, name):
43
+ def add_package_def(self, name, component_part_name=None, boundary_points=None):
44
44
  """Add a package definition.
45
45
 
46
46
  Parameters
47
47
  ----------
48
48
  name: str
49
49
  Name of the package definition.
50
+ component_part_name : str, optional
51
+ Part name of the component.
52
+ boundary_points : list, optional
53
+ Boundary points which define the shape of the package.
50
54
 
51
55
  Returns
52
56
  -------
53
57
 
54
58
  """
55
- package_def = PackageDef(self._pedb, name=name)
59
+ package_def = PackageDef(
60
+ self._pedb, name=name, component_part_name=component_part_name, extent_bounding_box=boundary_points
61
+ )
56
62
  return package_def