pyedb 0.7.0__py3-none-any.whl → 0.7.1__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 (32) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/dotnet/clr_module.py +1 -1
  3. pyedb/dotnet/edb.py +6 -7
  4. pyedb/dotnet/edb_core/components.py +11 -11
  5. pyedb/dotnet/edb_core/configuration.py +199 -24
  6. pyedb/dotnet/edb_core/definition/component_def.py +9 -0
  7. pyedb/dotnet/edb_core/definition/package_def.py +27 -0
  8. pyedb/dotnet/edb_core/edb_data/components_data.py +2 -1
  9. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +14 -13
  10. pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +2 -2
  11. pyedb/dotnet/edb_core/edb_data/layer_data.py +8 -3
  12. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +6 -5
  13. pyedb/dotnet/edb_core/edb_data/primitives_data.py +12 -11
  14. pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1 -1
  15. pyedb/dotnet/edb_core/edb_data/sources.py +10 -0
  16. pyedb/dotnet/edb_core/layout.py +59 -0
  17. pyedb/dotnet/edb_core/materials.py +637 -541
  18. pyedb/dotnet/edb_core/padstack.py +57 -6
  19. pyedb/dotnet/edb_core/siwave.py +9 -2
  20. pyedb/dotnet/edb_core/stackup.py +108 -94
  21. pyedb/dotnet/edb_core/utilities/__init__.py +3 -0
  22. pyedb/dotnet/edb_core/utilities/heatsink.py +69 -0
  23. pyedb/exceptions.py +6 -0
  24. pyedb/generic/filesystem.py +7 -3
  25. pyedb/generic/general_methods.py +4 -0
  26. pyedb/generic/process.py +4 -1
  27. pyedb/generic/settings.py +10 -0
  28. {pyedb-0.7.0.dist-info → pyedb-0.7.1.dist-info}/METADATA +31 -53
  29. {pyedb-0.7.0.dist-info → pyedb-0.7.1.dist-info}/RECORD +32 -29
  30. /pyedb/dotnet/edb_core/{edb_data → utilities}/simulation_setup.py +0 -0
  31. {pyedb-0.7.0.dist-info → pyedb-0.7.1.dist-info}/LICENSE +0 -0
  32. {pyedb-0.7.0.dist-info → pyedb-0.7.1.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.7.1"
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
@@ -4142,8 +4141,8 @@ class Edb(Database):
4142
4141
  loss_tg_variable = "$loss_tangent_{}".format(mat_name)
4143
4142
  loss_tg_variable = self._clean_string_for_variable_name(loss_tg_variable)
4144
4143
  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
4144
+ self.add_design_variable(loss_tg_variable, material.dielectric_loss_tangent)
4145
+ material.dielectric_loss_tangent = loss_tg_variable
4147
4146
  parameters.append(loss_tg_variable)
4148
4147
  else:
4149
4148
  sigma_variable = "$sigma_{}".format(mat_name)
@@ -1408,7 +1408,7 @@ class Components(object):
1408
1408
 
1409
1409
  @pyedb_function_handler()
1410
1410
  def create_rlc_component(
1411
- self, pins, component_name="", r_value=1.0, c_value=1e-9, l_value=1e-9, is_parallel=False
1411
+ self, pins, component_name="", r_value=None, c_value=None, l_value=None, is_parallel=False
1412
1412
  ): # pragma: no cover
1413
1413
  """Create physical Rlc component.
1414
1414
 
@@ -1454,9 +1454,9 @@ class Components(object):
1454
1454
  placement_layer=None,
1455
1455
  component_part_name=None,
1456
1456
  is_rlc=False,
1457
- r_value=0,
1458
- c_value=0,
1459
- l_value=0,
1457
+ r_value=None,
1458
+ c_value=None,
1459
+ l_value=None,
1460
1460
  is_parallel=False,
1461
1461
  ):
1462
1462
  """Create a component from pins.
@@ -1523,21 +1523,21 @@ class Components(object):
1523
1523
  if is_rlc and len(pins) == 2:
1524
1524
  rlc = self._edb.utility.utility.Rlc()
1525
1525
  rlc.IsParallel = is_parallel
1526
- if r_value:
1526
+ if r_value is None:
1527
+ rlc.REnabled = False
1528
+ else:
1527
1529
  rlc.REnabled = True
1528
1530
  rlc.R = self._get_edb_value(r_value)
1531
+ if l_value is None:
1532
+ rlc.LEnabled = False
1529
1533
  else:
1530
- rlc.REnabled = False
1531
- if l_value:
1532
1534
  rlc.LEnabled = True
1533
1535
  rlc.L = self._get_edb_value(l_value)
1536
+ if c_value is None:
1537
+ rlc.CEnabled = False
1534
1538
  else:
1535
- rlc.LEnabled = False
1536
- if c_value:
1537
1539
  rlc.CEnabled = True
1538
1540
  rlc.C = self._get_edb_value(c_value)
1539
- else:
1540
- rlc.CEnabled = False
1541
1541
  if rlc.REnabled and not rlc.CEnabled and not rlc.CEnabled:
1542
1542
  new_cmp.SetComponentType(self._edb.definition.ComponentType.Resistor)
1543
1543
  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)
@@ -389,7 +420,10 @@ class Configuration:
389
420
  else:
390
421
  self._pedb.logger.warning("Setup {} already existing. Editing it.".format(name))
391
422
  edb_setup = self._pedb.setups[name]
392
- edb_setup.si_slider_position = setup["si_slider_position"]
423
+ if "si_slider_position" in setup:
424
+ edb_setup.si_slider_position = setup["si_slider_position"]
425
+ if "pi_slider_position" in setup:
426
+ edb_setup.pi_slider_position = setup["pi_slider_position"]
393
427
 
394
428
  if "freq_sweep" in setup:
395
429
  for fsweep in setup["freq_sweep"]:
@@ -476,14 +510,23 @@ class Configuration:
476
510
  comp_def_name = sp["component_definition"]
477
511
  comp_def = self._pedb.definitions.component[comp_def_name]
478
512
  comp_def.add_n_port_model(fpath, sp_name)
513
+ comp_list = dict()
479
514
  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)
515
+ comp_list.update(
516
+ {refdes: comp for refdes, comp in comp_def.components.items() if refdes not in sp["components"]}
517
+ )
483
518
  else:
484
- for refdes, comp in comp_def.components.items():
485
- if refdes in sp["components"]:
486
- comp.use_s_parameter_model(sp_name)
519
+ comp_list.update(
520
+ {refdes: comp for refdes, comp in comp_def.components.items() if refdes in sp["components"]}
521
+ )
522
+
523
+ for refdes, comp in comp_list.items():
524
+ if "reference_net_per_component" in sp:
525
+ ref_net_per_comp = sp["reference_net_per_component"]
526
+ ref_net = ref_net_per_comp[refdes] if refdes in ref_net_per_comp else sp["reference_net"]
527
+ else:
528
+ ref_net = sp["reference_net"]
529
+ comp.use_s_parameter_model(sp_name, reference_net=ref_net)
487
530
 
488
531
  @pyedb_function_handler
489
532
  def _load_spice_models(self):
@@ -536,3 +579,135 @@ class Configuration:
536
579
  self._s_parameter_library = general["s_parameter_library"]
537
580
  if "spice_model_library" in general:
538
581
  self._spice_model_library = general["spice_model_library"]
582
+
583
+ @pyedb_function_handler
584
+ def _load_boundaries(self):
585
+ """Imports boundary information from JSON."""
586
+ boundaries = self.data["boundaries"]
587
+
588
+ open_region = boundaries.get("open_region", None)
589
+ if open_region:
590
+ self._pedb.hfss.hfss_extent_info.use_open_region = open_region
591
+
592
+ open_region_type = boundaries.get("open_region_type", None)
593
+ if open_region_type:
594
+ self._pedb.hfss.hfss_extent_info.open_region_type = open_region_type
595
+
596
+ pml_visible = boundaries.get("pml_visible", None)
597
+ if pml_visible:
598
+ self._pedb.hfss.hfss_extent_info.is_pml_visible = pml_visible
599
+
600
+ pml_operation_frequency = boundaries.get("pml_operation_frequency", None)
601
+ if pml_operation_frequency:
602
+ self._pedb.hfss.hfss_extent_info.operating_freq = pml_operation_frequency
603
+
604
+ pml_radiation_factor = boundaries.get("pml_radiation_factor", None)
605
+ if pml_radiation_factor:
606
+ self._pedb.hfss.hfss_extent_info.radiation_level = pml_radiation_factor
607
+
608
+ dielectric_extents_type = boundaries.get("dielectric_extents_type", None)
609
+ if dielectric_extents_type:
610
+ self._pedb.hfss.hfss_extent_info.extent_type = dielectric_extents_type
611
+
612
+ dielectric_base_polygon = boundaries.get("dielectric_base_polygon", None)
613
+ if dielectric_base_polygon:
614
+ self._pedb.hfss.hfss_extent_info.dielectric_base_polygon = dielectric_base_polygon
615
+
616
+ horizontal_padding = boundaries.get("horizontal_padding", None)
617
+ if horizontal_padding:
618
+ self._pedb.hfss.hfss_extent_info.dielectric_extent_size = horizontal_padding
619
+
620
+ honor_primitives_on_dielectric_layers = boundaries.get("honor_primitives_on_dielectric_layers", None)
621
+ if honor_primitives_on_dielectric_layers:
622
+ self._pedb.hfss.hfss_extent_info.honor_user_dielectric = honor_primitives_on_dielectric_layers
623
+
624
+ air_box_extents_type = boundaries.get("air_box_extents_type", None)
625
+ if air_box_extents_type:
626
+ self._pedb.hfss.hfss_extent_info.extent_type = air_box_extents_type
627
+
628
+ air_box_truncate_model_ground_layers = boundaries.get("air_box_truncate_model_ground_layers", None)
629
+ if air_box_truncate_model_ground_layers:
630
+ self._pedb.hfss.hfss_extent_info.truncate_air_box_at_ground = air_box_truncate_model_ground_layers
631
+
632
+ air_box_horizontal_padding = boundaries.get("air_box_horizontal_padding", None)
633
+ if air_box_horizontal_padding:
634
+ self._pedb.hfss.hfss_extent_info.air_box_horizontal_extent = air_box_horizontal_padding
635
+
636
+ air_box_positive_vertical_padding = boundaries.get("air_box_positive_vertical_padding", None)
637
+ if air_box_positive_vertical_padding:
638
+ self._pedb.hfss.hfss_extent_info.air_box_positive_vertical_extent = air_box_positive_vertical_padding
639
+
640
+ air_box_negative_vertical_padding = boundaries.get("air_box_negative_vertical_padding", None)
641
+ if air_box_positive_vertical_padding:
642
+ self._pedb.hfss.hfss_extent_info.air_box_negative_vertical_extent = air_box_negative_vertical_padding
643
+
644
+ @pyedb_function_handler
645
+ def _load_operations(self):
646
+ """Imports operation information from JSON."""
647
+ operations = self.data["operations"]
648
+ cutout = operations.get("cutout", None)
649
+ if cutout:
650
+ self._pedb.cutout(**cutout)
651
+
652
+ @pyedb_function_handler
653
+ def _load_padstacks(self):
654
+ """Imports padstack information from JSON."""
655
+ padstacks = self.data["padstacks"]
656
+ definitions = padstacks.get("definitions", None)
657
+ if definitions:
658
+ padstack_defs = self._pedb.padstacks.definitions
659
+ for value in definitions:
660
+ pdef = padstack_defs[value["name"]]
661
+ if "hole_diameter" in value:
662
+ pdef.hole_diameter = value["hole_diameter"]
663
+ if "hole_plating_thickness" in value:
664
+ pdef.hole_plating_thickness = value["hole_plating_thickness"]
665
+ if "hole_material" in value:
666
+ pdef.material = value["hole_material"]
667
+ if "hole_range" in value:
668
+ pdef.hole_range = value["hole_range"]
669
+ instances = padstacks.get("instances", None)
670
+ if instances:
671
+ padstack_instances = self._pedb.padstacks.instances_by_name
672
+ for value in instances:
673
+ inst = padstack_instances[value["name"]]
674
+ backdrill_top = value.get("backdrill_top", None)
675
+ if backdrill_top:
676
+ inst.set_backdrill_top(
677
+ backdrill_top["drill_to_layer"], backdrill_top["drill_diameter"], backdrill_top["stub_length"]
678
+ )
679
+ backdrill_bottom = value.get("backdrill_bottom", None)
680
+ if backdrill_top:
681
+ inst.set_backdrill_bottom(
682
+ backdrill_bottom["drill_to_layer"],
683
+ backdrill_bottom["drill_diameter"],
684
+ backdrill_bottom["stub_length"],
685
+ )
686
+
687
+ @pyedb_function_handler
688
+ def _load_package_def(self):
689
+ """Imports package definition information from JSON."""
690
+ comps = self._pedb.components.components
691
+ for pkgd in self.data["package_definitions"]:
692
+ name = pkgd["name"]
693
+ if name in self._pedb.definitions.package:
694
+ self._pedb.definitions.package[name].delete()
695
+ package_def = PackageDef(self._pedb, name=name)
696
+ package_def.maximum_power = pkgd["maximum_power"]
697
+ package_def.therm_cond = pkgd["therm_cond"]
698
+ package_def.theta_jb = pkgd["theta_jb"]
699
+ package_def.theta_jc = pkgd["theta_jc"]
700
+ package_def.height = pkgd["height"]
701
+
702
+ heatsink = pkgd.get("heatsink", None)
703
+ if heatsink:
704
+ package_def.set_heatsink(
705
+ heatsink["fin_base_height"],
706
+ heatsink["fin_height"],
707
+ heatsink["fin_orientation"],
708
+ heatsink["fin_spacing"],
709
+ heatsink["fin_thickness"],
710
+ )
711
+ json_comps = pkgd["components"] if isinstance(pkgd["components"], list) else [pkgd["components"]]
712
+ for i in json_comps:
713
+ comps[i].package_def = name
@@ -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 = {}
@@ -67,6 +67,11 @@ class PackageDef(ObjBase):
67
67
  edb_object.SetExteriorBoundary(polygon)
68
68
  return edb_object
69
69
 
70
+ @pyedb_function_handler
71
+ def delete(self):
72
+ """Delete a package definition object from the database."""
73
+ return self._edb_object.Delete()
74
+
70
75
  @property
71
76
  def maximum_power(self):
72
77
  """Maximum power of the package."""
@@ -116,3 +121,25 @@ class PackageDef(ObjBase):
116
121
  def height(self, value):
117
122
  value = self._pedb.edb_value(value)
118
123
  self._edb_object.SetHeight(value)
124
+
125
+ @pyedb_function_handler
126
+ def set_heatsink(self, fin_base_height, fin_height, fin_orientation, fin_spacing, fin_thickness):
127
+ from pyedb.dotnet.edb_core.utilities.heatsink import HeatSink
128
+
129
+ heatsink = HeatSink(self._pedb)
130
+ heatsink.fin_base_height = fin_base_height
131
+ heatsink.fin_height = fin_height
132
+ heatsink.fin_orientation = fin_orientation
133
+ heatsink.fin_spacing = fin_spacing
134
+ heatsink.fin_thickness = fin_thickness
135
+ self._edb_object.SetHeatSink(heatsink._edb_object)
136
+
137
+ @property
138
+ def heatsink(self):
139
+ from pyedb.dotnet.edb_core.utilities.heatsink import HeatSink
140
+
141
+ flag, edb_object = self._edb_object.GetHeatSink()
142
+ if flag:
143
+ return HeatSink(self._pedb, edb_object)
144
+ else:
145
+ return None
@@ -375,7 +375,7 @@ class EDBComponent(object):
375
375
 
376
376
  @property
377
377
  def solder_ball_diameter(self):
378
- """Solder ball diameter"""
378
+ """Solder ball diameter."""
379
379
  if "GetSolderBallProperty" in dir(self.component_property):
380
380
  result = self.component_property.GetSolderBallProperty().GetDiameter()
381
381
  succeed = result[0]
@@ -850,6 +850,7 @@ class EDBComponent(object):
850
850
  @property
851
851
  def is_top_mounted(self):
852
852
  """Check if a component is mounted on top or bottom of the layout.
853
+
853
854
  Returns
854
855
  -------
855
856
  bool
@@ -39,14 +39,14 @@ class HfssExtentInfo:
39
39
  self._pedb = pedb
40
40
 
41
41
  self._hfss_extent_info_type = {
42
- "BoundingBox": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.BoundingBox,
43
- "Conforming": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.Conforming,
44
- "ConvexHull": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.ConvexHull,
45
- "Polygon": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.Polygon,
42
+ "bounding_box": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.BoundingBox,
43
+ "conforming": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.Conforming,
44
+ "convexHull": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.ConvexHull,
45
+ "polygon": self._pedb.edb_api.utility.utility.HFSSExtentInfoType.Polygon,
46
46
  }
47
47
  self._open_region_type = {
48
- "Radiation": self._pedb.edb_api.utility.utility.OpenRegionType.Radiation,
49
- "PML": self._pedb.edb_api.utility.utility.OpenRegionType.PML,
48
+ "radiation": self._pedb.edb_api.utility.utility.OpenRegionType.Radiation,
49
+ "pml": self._pedb.edb_api.utility.utility.OpenRegionType.PML,
50
50
  }
51
51
 
52
52
  @pyedb_function_handler()
@@ -195,18 +195,19 @@ class HfssExtentInfo:
195
195
  @property
196
196
  def dielectric_extent_type(self):
197
197
  """Dielectric extent type."""
198
- return self._edb_hfss_extent_info.DielectricExtentType.ToString()
198
+ return self._edb_hfss_extent_info.DielectricExtentType.ToString().lower()
199
199
 
200
200
  @dielectric_extent_type.setter
201
201
  def dielectric_extent_type(self, value):
202
+ value = "bounding_box" if value == "BoundingBox" else value
202
203
  info = self._edb_hfss_extent_info
203
- info.DielectricExtentType = self._hfss_extent_info_type[value]
204
+ info.DielectricExtentType = self._hfss_extent_info_type[value.lower()]
204
205
  self._update_hfss_extent_info(info)
205
206
 
206
207
  @property
207
208
  def extent_type(self):
208
209
  """Extent type."""
209
- return self._edb_hfss_extent_info.ExtentType.ToString()
210
+ return self._edb_hfss_extent_info.ExtentType.ToString().lower()
210
211
 
211
212
  @extent_type.setter
212
213
  def extent_type(self, value):
@@ -239,17 +240,17 @@ class HfssExtentInfo:
239
240
  @property
240
241
  def open_region_type(self):
241
242
  """Open region type."""
242
- return self._edb_hfss_extent_info.OpenRegionType.ToString()
243
+ return self._edb_hfss_extent_info.OpenRegionType.ToString().lower()
243
244
 
244
245
  @open_region_type.setter
245
246
  def open_region_type(self, value):
246
247
  info = self._edb_hfss_extent_info
247
- info.OpenRegionType = self._open_region_type[value]
248
+ info.OpenRegionType = self._open_region_type[value.lower()]
248
249
  self._update_hfss_extent_info(info)
249
250
 
250
251
  @property
251
252
  def operating_freq(self):
252
- """Operating frequency.
253
+ """PML Operating frequency.
253
254
 
254
255
  Returns
255
256
  -------
@@ -266,7 +267,7 @@ class HfssExtentInfo:
266
267
 
267
268
  @property
268
269
  def radiation_level(self):
269
- """Radiation level."""
270
+ """PML Radiation level to calculate the thickness of boundary."""
270
271
  return EdbValue(self._edb_hfss_extent_info.RadiationLevel)
271
272
 
272
273
  @radiation_level.setter
@@ -21,11 +21,11 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  from pyedb.dotnet.clr_module import Tuple
24
- from pyedb.dotnet.edb_core.edb_data.simulation_setup import (
24
+ from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
25
+ from pyedb.dotnet.edb_core.utilities.simulation_setup import (
25
26
  BaseSimulationSetup,
26
27
  EdbFrequencySweep,
27
28
  )
28
- from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
29
29
  from pyedb.generic.general_methods import generate_unique_name, pyedb_function_handler
30
30
 
31
31
 
@@ -553,6 +553,7 @@ class StackupLayerEdbClass(LayerEdbClass):
553
553
  dict_out[k[1:]] = v
554
554
  return dict_out
555
555
 
556
+ # TODO: This method might need some refactoring
556
557
  def _load_layer(self, layer):
557
558
  if layer:
558
559
  self.color = layer["color"]
@@ -560,13 +561,17 @@ class StackupLayerEdbClass(LayerEdbClass):
560
561
  if isinstance(layer["material"], str):
561
562
  self.material = layer["material"]
562
563
  else:
563
- self._pclass._pedb.materials._load_materials(layer["material"])
564
- self.material = layer["material"]["name"]
564
+ material_data = layer["material"]
565
+ if material_data is not None:
566
+ self._pclass._pedb.materials.add_material(**material_data)
567
+ self.material = layer["material"]["name"]
565
568
  if layer["dielectric_fill"]:
566
569
  if isinstance(layer["dielectric_fill"], str):
567
570
  self.dielectric_fill = layer["dielectric_fill"]
568
571
  else:
569
- self._pclass._pedb.materials._load_materials(layer["dielectric_fill"])
572
+ dielectric_data = layer["dielectric_fill"]
573
+ if dielectric_data is not None:
574
+ self._pclass._pedb.materials.add_material(**dielectric_data)
570
575
  self.dielectric_fill = layer["dielectric_fill"]["name"]
571
576
  self.thickness = layer["thickness"]
572
577
  self.etch_factor = layer["etch_factor"]
@@ -688,6 +688,7 @@ class EDBPadstack(object):
688
688
  float
689
689
  Thickness of the hole plating if present.
690
690
  """
691
+ value = self._get_edb_value(value).ToDouble()
691
692
  hr = 200 * float(value) / float(self.hole_properties[0])
692
693
  self.hole_plating_ratio = hr
693
694
 
@@ -808,13 +809,13 @@ class EDBPadstack(object):
808
809
  if convert_only_signal_vias:
809
810
  signal_nets = [i for i in list(self._ppadstack._pedb.nets.signal_nets.keys())]
810
811
  topl, topz, bottoml, bottomz = self._ppadstack._pedb.stackup.stackup_limits(True)
811
- try:
812
+ if self.via_start_layer in layers:
812
813
  start_elevation = layers[self.via_start_layer].lower_elevation
813
- except KeyError: # pragma: no cover
814
+ else:
814
815
  start_elevation = layers[self.instances[0].start_layer].lower_elevation
815
- try:
816
- stop_elevation = layers[self.via_start_layer].upper_elevation
817
- except KeyError: # pragma: no cover
816
+ if self.via_stop_layer in layers:
817
+ stop_elevation = layers[self.via_stop_layer].upper_elevation
818
+ else:
818
819
  stop_elevation = layers[self.instances[0].stop_layer].upper_elevation
819
820
 
820
821
  diel_thick = abs(start_elevation - stop_elevation)