pyedb 0.15.0__py3-none-any.whl → 0.16.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyedb might be problematic. Click here for more details.

pyedb/__init__.py CHANGED
@@ -44,7 +44,7 @@ deprecation_warning()
44
44
  #
45
45
 
46
46
  pyedb_path = os.path.dirname(__file__)
47
- __version__ = "0.15.0"
47
+ __version__ = "0.16.0"
48
48
  version = __version__
49
49
 
50
50
  #
@@ -22,9 +22,7 @@
22
22
 
23
23
 
24
24
  class CfgBase:
25
- @property
26
- def protected_attributes(self):
27
- return []
25
+ protected_attributes = []
28
26
 
29
27
  def get_attributes(self, exclude=None):
30
28
  attrs = {i: j for i, j in self.__dict__.items() if i not in self.protected_attributes}
@@ -51,6 +51,8 @@ class CfgRlcModel(CfgBase):
51
51
 
52
52
 
53
53
  class CfgComponent(CfgBase):
54
+ protected_attributes = ["reference_designator"]
55
+
54
56
  def __init__(self, **kwargs):
55
57
  self.enabled = kwargs.get("enabled", None)
56
58
 
@@ -65,15 +67,11 @@ class CfgComponent(CfgBase):
65
67
 
66
68
  self.rlc_model = [CfgRlcModel(**rlc_m) for rlc_m in rlc_models]
67
69
 
68
- @property
69
- def protected_attributes(self):
70
- return ["reference_designator"]
71
-
72
70
 
73
71
  class CfgComponents:
74
- def __init__(self, pedb, data):
72
+ def __init__(self, pedb, components_data):
75
73
  self._pedb = pedb
76
- self.components = [CfgComponent(**comp) for comp in data]
74
+ self.components = [CfgComponent(**comp) for comp in components_data]
77
75
 
78
76
  def apply(self):
79
77
  comps_in_db = self._pedb.components
@@ -31,7 +31,7 @@ from pyedb.configuration.cfg_padstacks import CfgPadstacks
31
31
  from pyedb.configuration.cfg_pin_groups import CfgPinGroup
32
32
  from pyedb.configuration.cfg_ports_sources import CfgPort, CfgSources
33
33
  from pyedb.configuration.cfg_s_parameter_models import CfgSParameterModel
34
- from pyedb.configuration.cfg_setup import CfgSetup
34
+ from pyedb.configuration.cfg_setup import CfgSetups
35
35
  from pyedb.configuration.cfg_spice_models import CfgSpiceModel
36
36
  from pyedb.configuration.cfg_stackup import CfgStackup
37
37
 
@@ -54,8 +54,7 @@ class CfgData(object):
54
54
  self, kwargs.get("nets", {}).get("signal_nets", []), kwargs.get("nets", {}).get("power_ground_nets", [])
55
55
  )
56
56
 
57
- # self.components = [CfgComponent(self, **component) for component in kwargs.get("components", [])]
58
- self.components = CfgComponents(self._pedb, data=kwargs.get("components", []))
57
+ self.components = CfgComponents(self._pedb, components_data=kwargs.get("components", []))
59
58
 
60
59
  self.padstacks = CfgPadstacks(self, kwargs.get("padstacks", None))
61
60
 
@@ -65,9 +64,7 @@ class CfgData(object):
65
64
 
66
65
  self.sources = [CfgSources(self, **source) for source in kwargs.get("sources", [])]
67
66
 
68
- self.setups = []
69
- if kwargs.get("setups", None):
70
- self.setups = [CfgSetup(self, setup) for setup in kwargs.get("setups", [])]
67
+ self.setups = CfgSetups(self._pedb, setups_data=kwargs.get("setups", []))
71
68
 
72
69
  self.stackup = CfgStackup(self._pedb, data=kwargs.get("stackup", {}))
73
70
 
@@ -27,6 +27,9 @@ from pyedb.dotnet.edb_core.definition.package_def import PackageDef
27
27
  class CfgPackage(CfgBase):
28
28
  """Configuration package class."""
29
29
 
30
+ # Attributes cannot be set to package definition class or don't exist in package definition class.
31
+ protected_attributes = ["apply_to_all", "components", "extent_bounding_box", "component_definition"]
32
+
30
33
  def __init__(self, **kwargs):
31
34
  self.name = kwargs.get("name", None)
32
35
  self.component_definition = kwargs.get("component_definition", None)
@@ -48,11 +51,6 @@ class CfgPackage(CfgBase):
48
51
  def heatsink(self, value):
49
52
  self._heatsink = value
50
53
 
51
- @property
52
- def protected_attributes(self):
53
- """Attributes cannot be set to package definition class or don't exist in package definition class."""
54
- return ["apply_to_all", "components", "extent_bounding_box", "component_definition"]
55
-
56
54
 
57
55
  class CfgHeatSink(CfgBase):
58
56
  """Configuration heat sink class."""
@@ -20,182 +20,220 @@
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 enum import Enum
24
-
25
-
26
- class FrequencySweep:
27
- def __init__(self, sweep_dict=None):
28
- self._sweep_dict = sweep_dict
29
- self.name = "PyEDB_sweep"
30
- self.type = self.SweepType.INTERPOLATING
31
- self.distribution = [self.Distribution()]
32
- if sweep_dict:
33
- self.name = self._sweep_dict.get("name", "PyEDB_sweep")
34
- frequencies = self._sweep_dict.get("frequencies", None)
35
- self._map_sweep_type()
36
- self.distribution = [self.Distribution(dist) for dist in frequencies]
37
-
38
- class SweepType(Enum):
39
- INTERPOLATING = 0
40
- DISCRETE = 1
41
-
42
- class Distribution:
43
- def __init__(self, distribution_dict=None):
44
- self.type = self.DistributionType.LINEAR_STEP
45
- self.start = "0GHz"
46
- self.stop = "10GHz"
47
- self.step = "10MHz"
48
- self.count = 100
49
- if distribution_dict:
50
- self.map(distribution_dict)
51
-
52
- class DistributionType(Enum):
53
- LINEAR_STEP = 0
54
- LINEAR_COUNT = 1
55
- LOG_SCALE = 2
56
-
57
- def map(self, distribution_dict):
58
- distribution_type = distribution_dict.get("distribution", "linear step")
59
- if distribution_type == "linear step":
60
- self.type = self.DistributionType.LINEAR_STEP
61
- elif distribution_type == "linear count":
62
- self.type = self.DistributionType.LINEAR_COUNT
63
- elif distribution_type == "log scale":
64
- self.type = self.DistributionType.LOG_SCALE
65
- else:
66
- self.type = self.DistributionType.LINEAR_STEP
67
- self.start = distribution_dict.get("start", "OGHz")
68
- self.stop = distribution_dict.get("stop", "10GHz")
69
- self.step = distribution_dict.get("step", "10MHz")
70
- self.count = distribution_dict.get("count", 100)
71
-
72
- def _map_sweep_type(self):
73
- if self._sweep_dict.get("type", "discrete"):
74
- self.type = self.SweepType.DISCRETE
75
- else:
76
- self.type = self.SweepType.INTERPOLATING
77
-
78
-
79
- class CfgDcSetup:
80
- def __init__(self):
81
- self.dc_slider_position = 1
82
- self.dcir_settings = DcIrSettings()
83
-
84
-
85
- class DcIrSettings:
86
- def __init__(self):
87
- self.export_dc_thermal_data = True
88
-
89
-
90
- class CfgSetup:
91
- def __init__(self, pdata, setup_dict=None):
92
- self._pedb = pdata._pedb
93
- self._setup_dict = None
94
- self.name = "PyEDB_setup"
95
- self.type = self.SetupType.HFSS
96
- self.f_adapt = "5GHz"
97
- self.max_num_passes = 30
98
- self.max_mag_delta_s = 0.02
99
- self.sweeps = [FrequencySweep()]
100
- self.dc_settings = CfgDcSetup()
101
- self.si_slider_position = 1
102
- self.pi_slider_position = 1
103
- if setup_dict:
104
- self._setup_dict = setup_dict
105
- self.name = setup_dict.get("name", "PyEDB_setup")
106
- self._map_setup_type(setup_dict.get("type", None))
107
- self.f_adapt = setup_dict.get("f_adapt", "5GHz")
108
- self.max_mag_delta_s = setup_dict.get("max_mag_delta_s", 0.02)
109
- if setup_dict.get("freq_sweep", None):
110
- self.sweeps = [FrequencySweep(sweep) for sweep in setup_dict.get("freq_sweep", None)]
111
- else:
112
- self.sweeps = []
113
- self.dc_settings.dc_slider_position = setup_dict.get("dc_slider_position", 1)
114
- if setup_dict.get("dc_ir_settings", None):
115
- dc_ir_dict = setup_dict.get("dc_ir_settings")
116
- self.dc_settings.dcir_settings.export_dc_thermal_data = dc_ir_dict.get("export_dc_thermal_data", True)
117
-
118
- def _map_setup_type(self, setup_type):
119
- if setup_type.upper() == "HFSS":
120
- self.type = self.SetupType.HFSS
121
- elif setup_type.upper() == "HFSS_PI":
122
- self.type = self.SetupType.HFSS_PI
123
- elif setup_type.upper() == "SIWAVE_SYZ":
124
- self.type = self.SetupType.SIWAVE_SYZ
125
- elif setup_type.upper() == "SIWAVE_DC":
126
- self.type = self.SetupType.SIWAVE_DC
127
- elif setup_type.upper() == "RAPTORX":
128
- self.type = self.SetupType.RAPTORX
129
- elif setup_type.upper() == "Q3D":
130
- self.type = self.SetupType.Q3D
131
- else:
132
- self.type = self.SetupType.HFSS
133
-
134
- class SetupType(Enum):
135
- HFSS = 0
136
- SIWAVE_SYZ = 1
137
- SIWAVE_DC = 2
138
- HFSS_PI = 3
139
- RAPTORX = 4
140
- Q3D = 5
23
+ from pyedb.configuration.cfg_common import CfgBase
24
+
25
+
26
+ class CfgFrequencies(CfgBase):
27
+ def __init__(self, **kwargs):
28
+ self.distribution = kwargs.get("distribution").replace(" ", "_") if kwargs.get("distribution") else None
29
+ self.start = kwargs.get("start")
30
+ self.stop = kwargs.get("stop")
31
+ self.increment = kwargs.get("increment", kwargs.get("points", kwargs.get("samples", kwargs.get("step"))))
32
+
33
+
34
+ class CfgSweepData(CfgBase):
35
+ def __init__(self, **kwargs):
36
+ self.name = kwargs.get("name")
37
+ self.type = kwargs.get("type").lower() if kwargs.get("type") else None
38
+ self.frequencies = []
39
+ for kw in kwargs.get("frequencies", []):
40
+ self.frequencies.append(CfgFrequencies(**kw))
41
+
42
+
43
+ class CfgSetup(CfgBase):
44
+ def __init__(self, pedb, **kwargs):
45
+ self._pedb = pedb
46
+ self.name = kwargs.get("name")
47
+ self.type = kwargs.get("type").lower() if kwargs.get("type") else None
48
+
49
+ self.freq_sweep = []
50
+ for i in kwargs.get("freq_sweep", []):
51
+ self.freq_sweep.append(CfgSweepData(**i))
52
+
53
+ def _apply_freq_sweep(self, edb_setup):
54
+ for i in self.freq_sweep:
55
+ f_set = []
56
+ kw = {}
57
+ for attr in i.get_attributes(exclude="name"):
58
+ if attr == "frequencies":
59
+ for f in i.frequencies:
60
+ f_set.append([f.distribution, f.start, f.stop, f.increment])
61
+ else:
62
+ kw[attr] = getattr(i, attr)
63
+ edb_setup.add_sweep(i.name, frequency_set=f_set, **kw)
64
+
65
+
66
+ class CfgSIwaveACSetup(CfgSetup):
67
+ def __init__(self, pedb, **kwargs):
68
+ super().__init__(pedb, **kwargs)
69
+ self.si_slider_position = kwargs.get("si_slider_position")
70
+ self.pi_slider_position = kwargs.get("pi_slider_position")
141
71
 
142
72
  def apply(self):
143
- edb_setup = None
144
- if self.type == self.SetupType.SIWAVE_DC:
145
- if self.name not in self._pedb.setups:
146
- edb_setup = self._pedb.create_siwave_dc_setup(self.name)
147
- self._pedb.logger.info("Setup {} created.".format(self.name))
148
- else:
149
- self._pedb.logger.warning("Setup {} already existing. Editing it.".format(self.name))
150
- edb_setup = self._pedb.setups[self.name]
151
- edb_setup.set_dc_slider(self.dc_settings.dc_slider_position)
152
- # TODO add DCIR settings in EDB setup
153
- elif self.type == self.SetupType.HFSS:
154
- if self.name not in self._pedb.setups:
155
- edb_setup = self._pedb.create_hfss_setup(self.name)
156
- self._pedb.logger.info("Setup {} created.".format(self.name))
157
- else:
158
- self._pedb.logger.warning("Setup {} already existing. Editing it.".format(self.name))
159
- edb_setup = self._pedb.setups[self.name]
160
- if not edb_setup.set_solution_single_frequency(self.f_adapt, self.max_num_passes, self.max_mag_delta_s):
161
- self._pedb.logger.errur(f"Failed to create HFSS simulation setup {self.name}")
162
- elif self.type == self.SetupType.SIWAVE_SYZ:
163
- if self.name not in self._pedb.setups:
164
- edb_setup = self._pedb.create_siwave_syz_setup(self.name)
165
- self._pedb.logger.info("Setup {} created.".format(self.name))
73
+ if self.name in self._pedb.setups:
74
+ raise "Setup {} already existing. Editing it.".format(self.name)
75
+
76
+ kwargs = (
77
+ {"si_slider_position": self.si_slider_position}
78
+ if self.si_slider_position is not None
79
+ else {"pi_slider_position": self.pi_slider_position}
80
+ )
81
+
82
+ edb_setup = self._pedb.create_siwave_syz_setup(name=self.name, **kwargs)
83
+ self._apply_freq_sweep(edb_setup)
84
+
85
+
86
+ class CfgSIwaveDCSetup(CfgSetup):
87
+ def __init__(self, pedb, **kwargs):
88
+ super().__init__(pedb, **kwargs)
89
+ self.dc_slider_position = kwargs.get("dc_slider_position")
90
+ self.dc_ir_settings = CfgDcIrSettings(**kwargs.get("dc_ir_settings", {}))
91
+ self.freq_sweep = None
92
+
93
+ def apply(self):
94
+ edb_setup = self._pedb.create_siwave_dc_setup(name=self.name, dc_slider_position=self.dc_slider_position)
95
+ for k, v in self.dc_ir_settings.get_attributes().items():
96
+ if k == "dc_slider_postion":
97
+ edb_setup.dc_settings.dc_slider_position = v
166
98
  else:
167
- self._pedb.logger.warning("Setup {} already existing. Editing it.".format(self.name))
168
- edb_setup = self._pedb.setups[self.name]
169
- edb_setup.si_slider_position = self.si_slider_position
170
- edb_setup.pi_slider_position = self.pi_slider_position
171
- for sweep in self.sweeps:
172
- for dist in sweep.distribution:
173
- freqs = []
174
- if dist.type == dist.DistributionType.LINEAR_STEP:
175
- freqs.append(
176
- [
177
- "linear scale",
178
- self._pedb.edb_value(dist.start).ToString(),
179
- self._pedb.edb_value(dist.stop).ToString(),
180
- self._pedb.edb_value(dist.step).ToString(),
181
- ]
182
- )
183
- elif dist.type == dist.DistributionType.LINEAR_COUNT:
184
- freqs.append(
185
- [
186
- "linear count",
187
- self._pedb.edb_value(dist.start).ToString(),
188
- self._pedb.edb_value(dist.stop).ToString(),
189
- int(dist.count),
190
- ]
191
- )
192
- elif dist.type == dist.DistributionType.LOG_SCALE:
193
- freqs.append(
194
- [
195
- "log scale",
196
- self._pedb.edb_value(dist.start).ToString(),
197
- self._pedb.edb_value(dist.stop).ToString(),
198
- int(dist.count),
199
- ]
200
- )
201
- edb_setup.add_frequency_sweep(sweep.name, frequency_sweep=freqs)
99
+ setattr(edb_setup.dc_ir_settings, k, v)
100
+
101
+
102
+ class CfgHFSSSetup(CfgSetup):
103
+ def __init__(self, pedb, **kwargs):
104
+ super().__init__(pedb, **kwargs)
105
+
106
+ self.f_adapt = kwargs.get("f_adapt")
107
+ self.max_num_passes = kwargs.get("max_num_passes")
108
+ self.max_mag_delta_s = kwargs.get("max_mag_delta_s")
109
+
110
+ self.mesh_operations = []
111
+ for i in kwargs.get("mesh_operations", []):
112
+ self.mesh_operations.append(CfgLengthMeshOperation(**i))
113
+
114
+ def apply(self):
115
+ if self.name in self._pedb.setups:
116
+ raise "Setup {} already existing. Editing it.".format(self.name)
117
+
118
+ edb_setup = self._pedb.create_hfss_setup(self.name)
119
+ edb_setup.set_solution_single_frequency(self.f_adapt, self.max_num_passes, self.max_mag_delta_s)
120
+
121
+ self._apply_freq_sweep(edb_setup)
122
+
123
+ for i in self.mesh_operations:
124
+ edb_setup.add_length_mesh_operation(
125
+ net_layer_list=i.nets_layers_list,
126
+ name=i.name,
127
+ # max_elements=i.max_elements,
128
+ max_length=i.max_length,
129
+ # restrict_elements=i.restrict_max_elements,
130
+ restrict_length=i.restrict_length,
131
+ refine_inside=i.refine_inside,
132
+ # mesh_region=i.mesh_region
133
+ )
134
+
135
+
136
+ class CfgDcIrSettings(CfgBase):
137
+ def __init__(self, **kwargs):
138
+ self.export_dc_thermal_data = kwargs.get("export_dc_thermal_data")
139
+
140
+
141
+ class CfgMeshOperation(CfgBase):
142
+ def __init__(self, **kwargs):
143
+ self.name = kwargs.get("name")
144
+ self.type = kwargs.get("type")
145
+ # self.mesh_region = kwargs.get("mesh_region")
146
+ self.nets_layers_list = kwargs.get("nets_layers_list", {})
147
+ self.refine_inside = kwargs.get("refine_inside", False)
148
+
149
+
150
+ class CfgLengthMeshOperation(CfgMeshOperation):
151
+ def __init__(self, **kwargs):
152
+ super().__init__(**kwargs)
153
+
154
+ # waiting bug review
155
+ # self.restrict_max_elements = kwargs.get("restrict_max_elements", True)
156
+ # self.max_elements = kwargs.get("max_elements", 1000)
157
+ self.restrict_length = kwargs.get("restrict_length", True)
158
+ self.max_length = kwargs.get("max_length", "1mm")
159
+
160
+
161
+ class CfgSetups:
162
+ def __init__(self, pedb, setups_data):
163
+ self._pedb = pedb
164
+ self.setups = []
165
+ for stp in setups_data:
166
+ if stp.get("type").lower() == "hfss":
167
+ self.setups.append(CfgHFSSSetup(self._pedb, **stp))
168
+ elif stp.get("type").lower() in ["siwave_ac", "siwave_syz"]:
169
+ self.setups.append(CfgSIwaveACSetup(self._pedb, **stp))
170
+ elif stp.get("type").lower() == "siwave_dc":
171
+ self.setups.append(CfgSIwaveDCSetup(self._pedb, **stp))
172
+
173
+ def apply(self):
174
+ for s in self.setups:
175
+ s.apply()
176
+
177
+ def get_data_from_db(self):
178
+ setups = []
179
+ for _, s in self._pedb.setups.items():
180
+ stp = {}
181
+ if s.type == "hfss":
182
+ for p_name in CfgHFSSSetup(self._pedb).__dict__:
183
+ if p_name.startswith("_"):
184
+ continue
185
+ elif p_name == "type":
186
+ stp[p_name] = s.type
187
+ elif p_name == "f_adapt":
188
+ stp[p_name] = list(s.adaptive_settings.adaptive_frequency_data_list)[0].adaptive_frequency
189
+ elif p_name == "max_num_passes":
190
+ stp[p_name] = list(s.adaptive_settings.adaptive_frequency_data_list)[0].max_passes
191
+ elif p_name == "max_mag_delta_s":
192
+ stp[p_name] = list(s.adaptive_settings.adaptive_frequency_data_list)[0].max_delta
193
+ elif p_name == "freq_sweep":
194
+ f_sweep = []
195
+ for _, sw in s.sweeps.items():
196
+ sweep_data = {}
197
+ for sw_p_name in CfgSweepData().__dict__:
198
+ if sw_p_name == "frequencies":
199
+ pass # Frequencies cannot be read from EDB
200
+ else:
201
+ sweep_data[sw_p_name] = getattr(sw, sw_p_name)
202
+ f_sweep.append(sweep_data)
203
+ stp["freq_sweep"] = f_sweep
204
+ elif p_name == "mesh_operations":
205
+ mops = []
206
+ for _, i in s.mesh_operations.items():
207
+ mop = {}
208
+ for mop_p_name in CfgLengthMeshOperation().__dict__:
209
+ mop[mop_p_name] = getattr(i, mop_p_name)
210
+ mops.append(mop)
211
+ stp["mesh_operations"] = mops
212
+ else:
213
+ stp[p_name] = getattr(s, p_name)
214
+
215
+ elif s.type == "siwave_ac":
216
+ for p_name in CfgSIwaveACSetup(self._pedb).__dict__:
217
+ if p_name.startswith("_"):
218
+ continue
219
+ elif p_name == "freq_sweep":
220
+ pass # Bug in EDB API
221
+ else:
222
+ stp[p_name] = getattr(s, p_name)
223
+ elif s.type == "siwave_dc":
224
+ for p_name in CfgSIwaveDCSetup(self._pedb).__dict__:
225
+ if p_name.startswith("_"):
226
+ continue
227
+ elif p_name == "freq_sweep":
228
+ pass
229
+ elif p_name == "dc_ir_settings":
230
+ dc_ir_s = {}
231
+ for dcir_p_name in CfgDcIrSettings().__dict__:
232
+ dc_ir_s[dcir_p_name] = getattr(s.dc_ir_settings, dcir_p_name)
233
+ stp["dc_ir_settings"] = dc_ir_s
234
+ elif p_name == "dc_slider_position":
235
+ stp[p_name] = getattr(s.dc_settings, p_name)
236
+ else:
237
+ stp[p_name] = getattr(s, p_name)
238
+ setups.append(stp)
239
+ return setups
@@ -127,7 +127,7 @@ class CfgStackup:
127
127
  attrs = mat_in_cfg.get_attributes()
128
128
  mat = self._pedb.materials.add_material(**attrs)
129
129
 
130
- def __get_materials_from_db(self):
130
+ def get_materials_from_db(self):
131
131
  materials = []
132
132
  for name, p in self._pedb.materials.materials.items():
133
133
  mat = {}
@@ -136,7 +136,7 @@ class CfgStackup:
136
136
  materials.append(mat)
137
137
  return materials
138
138
 
139
- def __get_layers_from_db(self):
139
+ def get_layers_from_db(self):
140
140
  layers = []
141
141
  for name, obj in self._pedb.stackup.all_layers.items():
142
142
  layer = {}
@@ -155,8 +155,8 @@ class CfgStackup:
155
155
  dict
156
156
  """
157
157
  stackup = {}
158
- materials = self.__get_materials_from_db()
158
+ materials = self.get_materials_from_db()
159
159
  stackup["materials"] = materials
160
- layers = self.__get_layers_from_db()
160
+ layers = self.get_layers_from_db()
161
161
  stackup["layers"] = layers
162
162
  return stackup
@@ -131,9 +131,8 @@ class Configuration:
131
131
  for source in self.cfg_data.sources:
132
132
  source.create()
133
133
 
134
- # Configure HFSS setup
135
- for setup in self.cfg_data.setups:
136
- setup.apply()
134
+ # Configure setup
135
+ self.cfg_data.setups.apply()
137
136
 
138
137
  # Configure stackup
139
138
  self.cfg_data.stackup.apply()
@@ -264,15 +263,18 @@ class Configuration:
264
263
  -------
265
264
 
266
265
  """
266
+ self._pedb.logger.info("Getting data from layout database.")
267
267
  data = {}
268
268
  if kwargs.get("stackup", False):
269
269
  data["stackup"] = self.cfg_data.stackup.get_data_from_db()
270
270
  if kwargs.get("package_definitions", False):
271
271
  data["package_definitions"] = self.cfg_data.package_definitions.get_data_from_db()
272
+ if kwargs.get("setups", False):
273
+ data["setups"] = self.cfg_data.setups.get_data_from_db()
272
274
 
273
275
  return data
274
276
 
275
- def export(self, file_path, stackup=True, package_definitions=True):
277
+ def export(self, file_path, stackup=True, package_definitions=True, setups=True):
276
278
  """Export the configuration data from layout to a file.
277
279
 
278
280
  Parameters
@@ -288,7 +290,7 @@ class Configuration:
288
290
  """
289
291
  file_path = file_path if isinstance(file_path, Path) else Path(file_path)
290
292
  file_path = file_path if file_path.suffix == ".json" else file_path.with_suffix(".json")
291
- data = self.get_data_from_db(stackup=stackup, package_definitions=package_definitions)
293
+ data = self.get_data_from_db(stackup=stackup, package_definitions=package_definitions, setups=setups)
292
294
  with open(file_path, "w") as f:
293
295
  json.dump(data, f, ensure_ascii=False, indent=4)
294
296
  return True if os.path.isfile(file_path) else False
pyedb/dotnet/edb.py CHANGED
@@ -3681,7 +3681,7 @@ class Edb(Database):
3681
3681
  return False
3682
3682
  return HFSSPISimulationSetup(self).create(name)
3683
3683
 
3684
- def create_siwave_syz_setup(self, name=None):
3684
+ def create_siwave_syz_setup(self, name=None, **kwargs):
3685
3685
  """Create a setup from a template.
3686
3686
 
3687
3687
  Parameters
@@ -3709,9 +3709,11 @@ class Edb(Database):
3709
3709
  if name in self.setups:
3710
3710
  return False
3711
3711
  setup = SiwaveSimulationSetup(self, name=name)
3712
+ for k, v in kwargs.items():
3713
+ setattr(setup, k, v)
3712
3714
  return self.setups[name]
3713
3715
 
3714
- def create_siwave_dc_setup(self, name=None):
3716
+ def create_siwave_dc_setup(self, name=None, **kwargs):
3715
3717
  """Create a setup from a template.
3716
3718
 
3717
3719
  Parameters
@@ -3736,6 +3738,8 @@ class Edb(Database):
3736
3738
  if name in self.setups:
3737
3739
  return False
3738
3740
  setup = SiwaveDCSimulationSetup(self, name=name)
3741
+ for k, v in kwargs.items():
3742
+ setattr(setup, k, v)
3739
3743
  return setup
3740
3744
 
3741
3745
  def calculate_initial_extent(self, expansion_factor):
@@ -149,10 +149,13 @@ class EdbLayout(object):
149
149
  _primitives_by_layer = {}
150
150
  for lay in self.layers:
151
151
  _primitives_by_layer[lay] = []
152
+ for lay in self._pedb.stackup.non_stackup_layers:
153
+ _primitives_by_layer[lay] = []
152
154
  for i in self._layout.primitives:
153
155
  try:
154
156
  lay = i.GetLayer().GetName()
155
- _primitives_by_layer[lay].append(cast(i, self._pedb))
157
+ if lay in _primitives_by_layer:
158
+ _primitives_by_layer[lay].append(cast(i, self._pedb))
156
159
  except:
157
160
  self._logger.warning(f"Failed to get layer on primitive {i}, skipping.")
158
161
  continue
@@ -20,22 +20,31 @@
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 enum import Enum
24
+
23
25
  from System import Tuple
24
26
 
25
27
  from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
26
28
 
27
29
 
30
+ class MeshOpType(Enum):
31
+ kMeshSetupBase = "base"
32
+ kMeshSetupLength = "length"
33
+ kMeshSetupSkinDepth = "skin_depth"
34
+ kNumMeshOpTypes = "num_mesh_op_types"
35
+
36
+
28
37
  class MeshOperation(object):
29
38
  """Mesh Operation Class."""
30
39
 
31
- def __init__(self, parent, mesh_operation):
40
+ def __init__(self, parent, edb_object):
32
41
  self._parent = parent
33
- self.mesh_operation = mesh_operation
42
+ self._edb_object = edb_object
34
43
  self._mesh_op_mapping = {
35
- "kMeshSetupBase": mesh_operation.TMeshOpType.kMeshSetupBase,
36
- "kMeshSetupLength": mesh_operation.TMeshOpType.kMeshSetupLength,
37
- "kMeshSetupSkinDepth": mesh_operation.TMeshOpType.kMeshSetupSkinDepth,
38
- "kNumMeshOpTypes": mesh_operation.TMeshOpType.kNumMeshOpTypes,
44
+ "kMeshSetupBase": self._edb_object.TMeshOpType.kMeshSetupBase,
45
+ "kMeshSetupLength": self._edb_object.TMeshOpType.kMeshSetupLength,
46
+ "kMeshSetupSkinDepth": self._edb_object.TMeshOpType.kMeshSetupSkinDepth,
47
+ "kNumMeshOpTypes": self._edb_object.TMeshOpType.kNumMeshOpTypes,
39
48
  }
40
49
 
41
50
  @property
@@ -47,7 +56,7 @@ class MeshOperation(object):
47
56
  bool
48
57
  ``True`` if mesh operation is used, ``False`` otherwise.
49
58
  """
50
- return self.mesh_operation.Enabled
59
+ return self._edb_object.Enabled
51
60
 
52
61
  @property
53
62
  def mesh_operation_type(self):
@@ -60,9 +69,14 @@ class MeshOperation(object):
60
69
 
61
70
  Returns
62
71
  -------
63
- int
72
+ str
64
73
  """
65
- return self.mesh_operation.MeshOpType.ToString()
74
+ return self._edb_object.MeshOpType.ToString()
75
+
76
+ @property
77
+ def type(self):
78
+ mop_type = self.mesh_operation_type
79
+ return MeshOpType[mop_type].value
66
80
 
67
81
  @property
68
82
  def mesh_region(self):
@@ -73,7 +87,7 @@ class MeshOperation(object):
73
87
  str
74
88
  Name of the mesh region.
75
89
  """
76
- return self.mesh_operation.MeshRegion
90
+ return self._edb_object.MeshRegion
77
91
 
78
92
  @property
79
93
  def name(self):
@@ -83,7 +97,7 @@ class MeshOperation(object):
83
97
  -------
84
98
  str
85
99
  """
86
- return self.mesh_operation.Name
100
+ return self._edb_object.Name
87
101
 
88
102
  @property
89
103
  def nets_layers_list(self):
@@ -99,7 +113,18 @@ class MeshOperation(object):
99
113
  Third element is represents whether if the mesh operation is enabled or disabled.
100
114
 
101
115
  """
102
- return self.mesh_operation.NetsLayersList
116
+ nets_layers = {}
117
+ for i in list(self._edb_object.NetsLayersList):
118
+ net = i.Item1
119
+ layer = i.Item2
120
+ flag = i.Item3
121
+ if not flag:
122
+ continue
123
+ if net not in nets_layers:
124
+ nets_layers[net] = [layer]
125
+ else:
126
+ nets_layers[net].append(layer)
127
+ return nets_layers
103
128
 
104
129
  @nets_layers_list.setter
105
130
  def nets_layers_list(self, values):
@@ -107,7 +132,7 @@ class MeshOperation(object):
107
132
  for net, layers in values.items():
108
133
  for layer in layers:
109
134
  temp.append(Tuple[str, str, bool](net, layer, True))
110
- self.mesh_operation.NetsLayersList = convert_py_list_to_net_list(temp)
135
+ self._edb_object.NetsLayersList = convert_py_list_to_net_list(temp)
111
136
 
112
137
  @property
113
138
  def refine_inside(self):
@@ -119,27 +144,23 @@ class MeshOperation(object):
119
144
  ``True`` if refine inside objects is used, ``False`` otherwise.
120
145
 
121
146
  """
122
- return self.mesh_operation.RefineInside
147
+ return self._edb_object.RefineInside
123
148
 
124
149
  @enabled.setter
125
150
  def enabled(self, value):
126
- self.mesh_operation.Enabled = value
127
- self._parent._update_setup()
151
+ self._edb_object.Enabled = value
128
152
 
129
153
  @mesh_region.setter
130
154
  def mesh_region(self, value):
131
- self.mesh_operation.MeshRegion = value
132
- self._parent._update_setup()
155
+ self._edb_object.MeshRegion = value
133
156
 
134
157
  @name.setter
135
158
  def name(self, value):
136
- self.mesh_operation.Name = value
137
- self._parent._update_setup()
159
+ self._edb_object.Name = value
138
160
 
139
161
  @refine_inside.setter
140
162
  def refine_inside(self, value):
141
- self.mesh_operation.RefineInside = value
142
- self._parent._update_setup()
163
+ self._edb_object.RefineInside = value
143
164
 
144
165
  @property
145
166
  def max_elements(self):
@@ -149,7 +170,7 @@ class MeshOperation(object):
149
170
  -------
150
171
  str
151
172
  """
152
- return self.mesh_operation.MaxElems
173
+ return int(self._edb_object.MaxElems)
153
174
 
154
175
  @property
155
176
  def restrict_max_elements(self):
@@ -159,12 +180,11 @@ class MeshOperation(object):
159
180
  -------
160
181
  bool
161
182
  """
162
- return self.mesh_operation.RestrictMaxElem
183
+ return self._edb_object.RestrictMaxElem
163
184
 
164
185
  @max_elements.setter
165
186
  def max_elements(self, value):
166
- self.mesh_operation.MaxElems = str(value)
167
- self._parent._update_setup()
187
+ self._edb_object.MaxElems = str(value)
168
188
 
169
189
  @restrict_max_elements.setter
170
190
  def restrict_max_elements(self, value):
@@ -174,11 +194,10 @@ class MeshOperation(object):
174
194
  -------
175
195
  bool
176
196
  """
177
- self.mesh_operation.RestrictMaxElem = value
178
- self._parent._update_setup()
197
+ self._edb_object.RestrictMaxElem = value
179
198
 
180
199
 
181
- class MeshOperationLength(MeshOperation, object):
200
+ class LengthMeshOperation(MeshOperation, object):
182
201
  """Mesh operation Length class.
183
202
  This class is accessible from Hfss Setup in EDB and add_length_mesh_operation method.
184
203
 
@@ -188,8 +207,8 @@ class MeshOperationLength(MeshOperation, object):
188
207
  >>> mop.max_elements = 3000
189
208
  """
190
209
 
191
- def __init__(self, parent, mesh_operation):
192
- MeshOperation.__init__(self, parent, mesh_operation)
210
+ def __init__(self, parent, edb_object):
211
+ MeshOperation.__init__(self, parent, edb_object)
193
212
 
194
213
  @property
195
214
  def max_length(self):
@@ -199,7 +218,7 @@ class MeshOperationLength(MeshOperation, object):
199
218
  -------
200
219
  str
201
220
  """
202
- return self.mesh_operation.MaxLength
221
+ return self._edb_object.MaxLength
203
222
 
204
223
  @property
205
224
  def restrict_length(self):
@@ -209,12 +228,11 @@ class MeshOperationLength(MeshOperation, object):
209
228
  -------
210
229
  bool
211
230
  """
212
- return self.mesh_operation.RestrictLength
231
+ return self._edb_object.RestrictLength
213
232
 
214
233
  @max_length.setter
215
234
  def max_length(self, value):
216
- self.mesh_operation.MaxLength = value
217
- self._parent._update_setup()
235
+ self._edb_object.MaxLength = value
218
236
 
219
237
  @restrict_length.setter
220
238
  def restrict_length(self, value):
@@ -224,11 +242,10 @@ class MeshOperationLength(MeshOperation, object):
224
242
  -------
225
243
  bool
226
244
  """
227
- self.mesh_operation.RestrictLength = value
228
- self._parent._update_setup()
245
+ self._edb_object.RestrictLength = value
229
246
 
230
247
 
231
- class MeshOperationSkinDepth(MeshOperation, object):
248
+ class SkinDepthMeshOperation(MeshOperation, object):
232
249
  """Mesh operation Skin Depth class.
233
250
  This class is accessible from Hfss Setup in EDB and assign_skin_depth_mesh_operation method.
234
251
 
@@ -238,8 +255,8 @@ class MeshOperationSkinDepth(MeshOperation, object):
238
255
  >>> mop.max_elements = 3000
239
256
  """
240
257
 
241
- def __init__(self, parent, mesh_operation):
242
- MeshOperation.__init__(self, parent, mesh_operation)
258
+ def __init__(self, parent, edb_object):
259
+ MeshOperation.__init__(self, parent, edb_object)
243
260
 
244
261
  @property
245
262
  def skin_depth(self):
@@ -249,12 +266,11 @@ class MeshOperationSkinDepth(MeshOperation, object):
249
266
  -------
250
267
  str
251
268
  """
252
- return self.mesh_operation.SkinDepth
269
+ return self._edb_object.SkinDepth
253
270
 
254
271
  @skin_depth.setter
255
272
  def skin_depth(self, value):
256
- self.mesh_operation.SkinDepth = value
257
- self._parent._update_setup()
273
+ self._edb_object.SkinDepth = value
258
274
 
259
275
  @property
260
276
  def surface_triangle_length(self):
@@ -264,12 +280,11 @@ class MeshOperationSkinDepth(MeshOperation, object):
264
280
  -------
265
281
  str
266
282
  """
267
- return self.mesh_operation.SurfTriLength
283
+ return self._edb_object.SurfTriLength
268
284
 
269
285
  @surface_triangle_length.setter
270
286
  def surface_triangle_length(self, value):
271
- self.mesh_operation.SurfTriLength = value
272
- self._parent._update_setup()
287
+ self._edb_object.SurfTriLength = value
273
288
 
274
289
  @property
275
290
  def number_of_layer_elements(self):
@@ -279,9 +294,8 @@ class MeshOperationSkinDepth(MeshOperation, object):
279
294
  -------
280
295
  str
281
296
  """
282
- return self.mesh_operation.NumLayers
297
+ return self._edb_object.NumLayers
283
298
 
284
299
  @number_of_layer_elements.setter
285
300
  def number_of_layer_elements(self, value):
286
- self.mesh_operation.NumLayers = str(value)
287
- self._parent._update_setup()
301
+ self._edb_object.NumLayers = str(value)
@@ -63,11 +63,6 @@ class SweepData(object):
63
63
  self._edb_object.Name = value
64
64
  self._update_sweep()
65
65
 
66
- @property
67
- def sweep_type(self):
68
- """Sweep type."""
69
- return
70
-
71
66
  @property
72
67
  def frequencies(self):
73
68
  """List of frequency points."""
@@ -159,6 +154,39 @@ class SweepData(object):
159
154
  """
160
155
  return self._edb_object.FreqSweepType.ToString()
161
156
 
157
+ @freq_sweep_type.setter
158
+ def freq_sweep_type(self, value):
159
+ edb_freq_sweep_type = self._edb_object.TFreqSweepType
160
+ if value in [0, "kInterpolatingSweep"]:
161
+ self._edb_object.FreqSweepType = edb_freq_sweep_type.kInterpolatingSweep
162
+ elif value in [1, "kDiscreteSweep"]:
163
+ self._edb_object.FreqSweepType = edb_freq_sweep_type.kDiscreteSweep
164
+ elif value in [2, "kBroadbandFastSweep"]:
165
+ self._edb_object.FreqSweepType = edb_freq_sweep_type.kBroadbandFastSweep
166
+ elif value in [3, "kNumSweepTypes"]:
167
+ self._edb_object.FreqSweepType = edb_freq_sweep_type.kNumSweepTypes
168
+ self._edb_object.FreqSweepType.ToString()
169
+
170
+ @property
171
+ def type(self):
172
+ """Sweep type."""
173
+ sw_type = self.freq_sweep_type
174
+ if sw_type == "kInterpolatingSweep":
175
+ return "interpolation"
176
+ elif sw_type == "kDiscreteSweep":
177
+ return "discrete"
178
+ elif sw_type == "kBroadbandFastSweep":
179
+ return "broadband"
180
+
181
+ @type.setter
182
+ def type(self, value):
183
+ if value == "interpolation":
184
+ self.freq_sweep_type = "kInterpolatingSweep"
185
+ elif value == "discrete":
186
+ self.freq_sweep_type = "kDiscreteSweep"
187
+ elif value == "broadband":
188
+ self.freq_sweep_type = "kBroadbandFastSweep"
189
+
162
190
  @property
163
191
  def interpolation_use_full_basis(self):
164
192
  """Flag indicating if full-basis elements is used.
@@ -318,19 +346,6 @@ class SweepData(object):
318
346
  self._edb_object.EnforcePassivity = value
319
347
  self._update_sweep()
320
348
 
321
- @freq_sweep_type.setter
322
- def freq_sweep_type(self, value):
323
- edb_freq_sweep_type = self._edb_object.TFreqSweepType
324
- if value in [0, "kInterpolatingSweep"]:
325
- self._edb_object.FreqSweepType = edb_freq_sweep_type.kInterpolatingSweep
326
- elif value in [1, "kDiscreteSweep"]:
327
- self._edb_object.FreqSweepType = edb_freq_sweep_type.kDiscreteSweep
328
- elif value in [2, "kBroadbandFastSweep"]:
329
- self._edb_object.FreqSweepType = edb_freq_sweep_type.kBroadbandFastSweep
330
- elif value in [3, "kNumSweepTypes"]:
331
- self._edb_object.FreqSweepType = edb_freq_sweep_type.kNumSweepTypes
332
- self._edb_object.FreqSweepType.ToString()
333
-
334
349
  @interpolation_use_full_basis.setter
335
350
  def interpolation_use_full_basis(self, value):
336
351
  self._edb_object.InterpUseFullBasis = value
@@ -506,20 +521,24 @@ class SweepData(object):
506
521
 
507
522
  def add(self, sweep_type, start, stop, increment):
508
523
  sweep_type = sweep_type.replace(" ", "_")
524
+ start = start.upper().replace("Z", "z") if isinstance(start, str) else str(start)
525
+ stop = stop.upper().replace("Z", "z") if isinstance(stop, str) else str(stop)
526
+ increment = increment.upper().replace("Z", "z") if isinstance(increment, str) else int(increment)
509
527
  if sweep_type in ["linear_count", "linear_scale"]:
510
528
  freqs = list(self._edb_object.SetFrequencies(start, stop, increment))
511
529
  elif sweep_type == "log_scale":
512
530
  freqs = list(self._edb_object.SetLogFrequencies(start, stop, increment))
513
531
  else:
514
532
  raise ValueError("sweep_type must be either 'linear_count', 'linear_scale' or 'log_scale")
515
- self.add_frequencies(freqs)
533
+ return self.add_frequencies(freqs)
516
534
 
517
535
  def add_frequencies(self, frequencies):
518
536
  if not isinstance(frequencies, list):
519
537
  frequencies = [frequencies]
520
538
  for i in frequencies:
521
- i = str(self._pedb.edb_value(i).ToDouble())
539
+ i = self._pedb.edb_value(i).ToString()
522
540
  self._edb_object.Frequencies.Add(i)
541
+ return list(self._edb_object.Frequencies)
523
542
 
524
543
  def clear(self):
525
544
  self._edb_object.Frequencies.Clear()
@@ -23,8 +23,8 @@
23
23
  import warnings
24
24
 
25
25
  from pyedb.dotnet.edb_core.sim_setup_data.data.mesh_operation import (
26
- MeshOperationLength,
27
- MeshOperationSkinDepth,
26
+ LengthMeshOperation,
27
+ SkinDepthMeshOperation,
28
28
  )
29
29
  from pyedb.dotnet.edb_core.sim_setup_data.data.settings import (
30
30
  AdaptiveSettings,
@@ -198,11 +198,11 @@ class HfssSimulationSetup(SimulationSetup):
198
198
  mesh_operations = {}
199
199
  for i in list(settings):
200
200
  if i.MeshOpType == i.TMeshOpType.kMeshSetupLength:
201
- mesh_operations[i.Name] = MeshOperationLength(self, i)
201
+ mesh_operations[i.Name] = LengthMeshOperation(self, i)
202
202
  elif i.MeshOpType == i.TMeshOpType.kMeshSetupSkinDepth:
203
- mesh_operations[i.Name] = MeshOperationSkinDepth(self, i)
203
+ mesh_operations[i.Name] = SkinDepthMeshOperation(self, i)
204
204
  elif i.MeshOpType == i.TMeshOpType.kMeshSetupBase:
205
- mesh_operations[i.Name] = MeshOperationSkinDepth(self, i)
205
+ mesh_operations[i.Name] = SkinDepthMeshOperation(self, i)
206
206
 
207
207
  return mesh_operations
208
208
 
@@ -244,18 +244,18 @@ class HfssSimulationSetup(SimulationSetup):
244
244
  """
245
245
  if not name:
246
246
  name = generate_unique_name("skin")
247
- mesh_operation = MeshOperationLength(self, self._pedb.simsetupdata.LengthMeshOperation())
248
- mesh_operation.mesh_region = mesh_region
249
- mesh_operation.name = name
250
- mesh_operation.nets_layers_list = net_layer_list
251
- mesh_operation.refine_inside = refine_inside
252
- mesh_operation.max_elements = str(max_elements)
253
- mesh_operation.max_length = max_length
254
- mesh_operation.restrict_length = restrict_length
255
- mesh_operation.restrict_max_elements = restrict_elements
256
- self.sim_setup_info.simulation_settings.MeshOperations.Add(mesh_operation.mesh_operation)
247
+ mop = LengthMeshOperation(self, self._pedb.simsetupdata.LengthMeshOperation())
248
+ mop.mesh_region = mesh_region
249
+ mop.name = name
250
+ mop.nets_layers_list = net_layer_list
251
+ mop.refine_inside = refine_inside
252
+ mop.max_elements = max_elements
253
+ mop.max_length = max_length
254
+ mop.restrict_length = restrict_length
255
+ mop.restrict_max_elements = restrict_elements
256
+ self.sim_setup_info.simulation_settings.MeshOperations.Add(mop._edb_object)
257
257
  self._update_setup()
258
- return mesh_operation
258
+ return mop
259
259
 
260
260
  def add_skin_depth_mesh_operation(
261
261
  self,
@@ -298,7 +298,7 @@ class HfssSimulationSetup(SimulationSetup):
298
298
  """
299
299
  if not name:
300
300
  name = generate_unique_name("length")
301
- mesh_operation = MeshOperationSkinDepth(self, self._pedb.simsetupdata.SkinDepthMeshOperation())
301
+ mesh_operation = SkinDepthMeshOperation(self, self._pedb.simsetupdata.SkinDepthMeshOperation())
302
302
  mesh_operation.mesh_region = mesh_region
303
303
  mesh_operation.name = name
304
304
  mesh_operation.nets_layers_list = net_layer_list
@@ -308,7 +308,7 @@ class HfssSimulationSetup(SimulationSetup):
308
308
  mesh_operation.number_of_layer_elements = number_of_layers
309
309
  mesh_operation.surface_triangle_length = surface_triangle_length
310
310
  mesh_operation.restrict_max_elements = restrict_elements
311
- self.sim_setup_info.simulation_settings.MeshOperations.Add(mesh_operation.mesh_operation)
311
+ self.sim_setup_info.simulation_settings.MeshOperations.Add(mesh_operation._edb_object)
312
312
  self._update_setup()
313
313
  return mesh_operation
314
314
 
@@ -21,6 +21,7 @@
21
21
  # SOFTWARE.
22
22
 
23
23
 
24
+ from enum import Enum
24
25
  import warnings
25
26
 
26
27
  from pyedb.dotnet.edb_core.sim_setup_data.data.sim_setup_info import SimSetupInfo
@@ -28,6 +29,23 @@ from pyedb.dotnet.edb_core.sim_setup_data.data.sweep_data import SweepData
28
29
  from pyedb.generic.general_methods import generate_unique_name
29
30
 
30
31
 
32
+ class SimulationSetupType(Enum):
33
+ kHFSS = "hfss"
34
+ kPEM = None
35
+ kSIwave = "siwave_ac"
36
+ kLNA = "lna"
37
+ kTransient = "transient"
38
+ kQEye = "quick_eye"
39
+ kVEye = "verif_eye"
40
+ kAMI = "ami"
41
+ kAnalysisOption = "analysis_option"
42
+ kSIwaveDCIR = "siwave_dc"
43
+ kSIwaveEMI = "siwave_emi"
44
+ kHFSSPI = "hfss_pi"
45
+ kDDRwizard = "ddrwizard"
46
+ kQ3D = "q3d"
47
+
48
+
31
49
  class AdaptiveType(object):
32
50
  (SingleFrequency, MultiFrequency, BroadBand) = range(0, 3)
33
51
 
@@ -92,6 +110,10 @@ class SimulationSetup(object):
92
110
  def setup_type(self):
93
111
  return self.sim_setup_info.sim_setup_type
94
112
 
113
+ @property
114
+ def type(self):
115
+ return SimulationSetupType[self.setup_type].value
116
+
95
117
  def _create(self, name=None, simulation_setup_type=""):
96
118
  """Create a simulation setup."""
97
119
  if not name:
@@ -137,9 +159,12 @@ class SimulationSetup(object):
137
159
  setup_utility = setup_type_mapping[sim_setup_type.ToString()]
138
160
  return setup_utility(edb_setup_info)
139
161
 
162
+ @property
163
+ def mesh_operations(self):
164
+ return {}
165
+
140
166
  def _update_setup(self):
141
167
  """Update setup in EDB."""
142
- # Update mesh operation
143
168
  # Update sweep
144
169
 
145
170
  # Replace setup
@@ -209,7 +234,7 @@ class SimulationSetup(object):
209
234
  else:
210
235
  return {i.name: i for i in self.sim_setup_info.sweep_data_list}
211
236
 
212
- def add_sweep(self, name, frequency_set: list = None):
237
+ def add_sweep(self, name, frequency_set: list = None, **kwargs):
213
238
  """Add frequency sweep.
214
239
 
215
240
  Parameters
@@ -232,10 +257,16 @@ class SimulationSetup(object):
232
257
  raise ValueError("Sweep {} already exists.".format(name))
233
258
 
234
259
  sweep_data = SweepData(self._pedb, name=name, sim_setup=self)
260
+ for k, v in kwargs.items():
261
+ if k in dir(sweep_data):
262
+ setattr(sweep_data, k, v)
263
+
235
264
  if frequency_set is None:
236
265
  sweep_type = "linear_scale"
237
266
  start, stop, increment = "50MHz", "5GHz", "50MHz"
238
267
  sweep_data.add(sweep_type, start, stop, increment)
268
+ elif len(frequency_set) == 0:
269
+ pass
239
270
  else:
240
271
  if not isinstance(frequency_set[0], list):
241
272
  frequency_set = [frequency_set]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyedb
3
- Version: 0.15.0
3
+ Version: 0.16.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>
@@ -22,7 +22,7 @@ Requires-Dist: dotnetcore2 ==3.1.23;platform_system=='Linux'
22
22
  Requires-Dist: pydantic>=2.6.4,<2.8
23
23
  Requires-Dist: toml == 0.10.2
24
24
  Requires-Dist: Rtree >= 1.2.0
25
- Requires-Dist: numpy>=1.20.0,<3
25
+ Requires-Dist: numpy>=1.20.0,<2
26
26
  Requires-Dist: ansys-sphinx-theme>=0.10.0,<0.17 ; extra == "doc"
27
27
  Requires-Dist: imageio>=2.30.0,<2.35 ; extra == "doc"
28
28
  Requires-Dist: ipython>=8.13.0,<8.26 ; extra == "doc"
@@ -41,7 +41,7 @@ Requires-Dist: sphinx_design>=0.4.0,<0.7 ; extra == "doc"
41
41
  Requires-Dist: matplotlib>=3.5.0,<3.10 ; extra == "full"
42
42
  Requires-Dist: pandas>=1.1.0,<2.3 ; extra == "full"
43
43
  Requires-Dist: matplotlib>=3.5.0,<3.10 ; extra == "tests"
44
- Requires-Dist: numpy>=1.20.0,<3 ; extra == "tests"
44
+ Requires-Dist: numpy>=1.20.0,<2 ; extra == "tests"
45
45
  Requires-Dist: mock>=5.1.0,<5.2 ; extra == "tests"
46
46
  Requires-Dist: pandas>=1.1.0,<2.3 ; extra == "tests"
47
47
  Requires-Dist: pytest>=7.4.0,<8.3 ; extra == "tests"
@@ -1,34 +1,34 @@
1
- pyedb/__init__.py,sha256=ikLG55mimstWvvlVdh0MuRlCP8bx_lJ9dx4rzqN0Fr8,1521
1
+ pyedb/__init__.py,sha256=HAdok962ENPcSNP4YCzTRB8o8iRR7OcPNmQT6sD08pE,1521
2
2
  pyedb/edb_logger.py,sha256=yNkXnoL2me7ubLT6O6r6ElVnkZ1g8fmfFYC_2XJZ1Sw,14950
3
3
  pyedb/exceptions.py,sha256=n94xluzUks6BA24vd_L6HkrvoP_H_l6__hQmqzdCyPo,111
4
4
  pyedb/siwave.py,sha256=p-j2AmJ3RPG9IKieDxiVPRhzRlXbjpxENP9GHAgT6l8,13086
5
5
  pyedb/configuration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  pyedb/configuration/cfg_boundaries.py,sha256=ckb-OfaObItwy-xc0LqkHJyeCfKC5vg668olPjZbaKo,6647
7
- pyedb/configuration/cfg_common.py,sha256=PVLYBv6pWiVAPa4haOsXdC87hH82rpZTkVW-MOqUObs,2020
8
- pyedb/configuration/cfg_components.py,sha256=5y_aQkHvXTO5TKDY3IaJxcxQMg7bNFnMJtlHVAwgTA8,6021
9
- pyedb/configuration/cfg_data.py,sha256=9qYp6ZNByi-od5riBNp4WthTuVilFTSH9dA4RhC-dlw,3938
7
+ pyedb/configuration/cfg_common.py,sha256=5ne78TTA0wHpbi804nsUd9SPxNKZvut_X_Miu-xDRgk,1982
8
+ pyedb/configuration/cfg_components.py,sha256=xirPvFvFwMgxHFcA4nnDbXTWZnAaCs9_4T4Kqv2AdtI,6005
9
+ pyedb/configuration/cfg_data.py,sha256=ENvPsPWYD-crwyHWkB0LBAfz9mHjxoVrszwVS_EL0i8,3772
10
10
  pyedb/configuration/cfg_general.py,sha256=0dtd-rkQt2aYR3EOL0c3sNuDuJs7htRos1OWck3rxaI,1626
11
11
  pyedb/configuration/cfg_nets.py,sha256=SCiBTUVHX3Ub91MEU88m0xcHIot_axT9QTFJ8LawppI,1880
12
12
  pyedb/configuration/cfg_operations.py,sha256=OzktdjLgHUm6_kCbMeuZ2mhUXfOIP6gXslmbkB7nZOM,3130
13
- pyedb/configuration/cfg_package_definition.py,sha256=jLL47ctoEUvkzk7pfh03qLhdv-vfGMdN1IfbboxnAo4,5342
13
+ pyedb/configuration/cfg_package_definition.py,sha256=f_RRT9R-3H5kHBlc4QSpjq9uQgYbaKQ78XXXrc_r3kg,5296
14
14
  pyedb/configuration/cfg_padstacks.py,sha256=5t799x_mfwLjCAic-B13v3I6FgDswysXdcKmeOxz4Uo,5571
15
15
  pyedb/configuration/cfg_pin_groups.py,sha256=aidsOXTHhEyE8UGRiT1nvyn-3sD0CU_n8RR19AmhQrk,2877
16
16
  pyedb/configuration/cfg_ports_sources.py,sha256=Wzs9hmEnOIPtiVXIfZgPM7TGsqV_t6ELbB71wSWG5_g,8166
17
17
  pyedb/configuration/cfg_s_parameter_models.py,sha256=NzS3eBjBSnd7ZDk_TsX04dqRcRXompjx1DxCe1UzWMw,2855
18
- pyedb/configuration/cfg_setup.py,sha256=XDpddzsIXWMHmrY-qonS5aQaFdS2OUZDQy5v8qWLCXE,8792
18
+ pyedb/configuration/cfg_setup.py,sha256=SPpNRLJusB-Cz2fDQkc6gkdilUqIlbNngoxF3zySt6g,10115
19
19
  pyedb/configuration/cfg_spice_models.py,sha256=tBY3okFiEffMGvBkpmZQrCrovpt-d62k51_WkkV4jqo,2435
20
- pyedb/configuration/cfg_stackup.py,sha256=YIFyfGAwnlErPGB5y87Viau_wxISofCHl5fPWVPdYC4,6597
21
- pyedb/configuration/configuration.py,sha256=At0W6PbIbV72nBzpLlLz0ElP99T5xMB9kNjmdjJ_dck,11275
20
+ pyedb/configuration/cfg_stackup.py,sha256=CX7uNN5QRoYW_MOObknP8003YchTS7PH9Oee7FG0VKU,6589
21
+ pyedb/configuration/configuration.py,sha256=5rpJgprlOt0PDyGCS0F1-ilktSRRD106twv2XTolN08,11444
22
22
  pyedb/dotnet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
23
  pyedb/dotnet/clr_module.py,sha256=Mo13Of3DVSA5HR-5xZEXOiHApIKy52CUxtJ2gPkEu1A,3406
24
- pyedb/dotnet/edb.py,sha256=QUw9Jv97vXTCB8G-RuILjURt4iYSvHDlwv9cKHOPCww,179407
24
+ pyedb/dotnet/edb.py,sha256=lgA6iwyrNFUupqzF4CicpomYBPAScOzm3DsFVYQOR6U,179565
25
25
  pyedb/dotnet/application/Variables.py,sha256=v_fxFJ6xjyyhk4uaMzWAbP-1FhXGuKsVNuyV1huaPME,77867
26
26
  pyedb/dotnet/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  pyedb/dotnet/edb_core/__init__.py,sha256=nIRLJ8VZLcMAp12zmGsnZ5x2BEEl7q_Kj_KAOXxVjpQ,52
28
28
  pyedb/dotnet/edb_core/components.py,sha256=T7gyIGKvwyocPwGCV806eQyghDiabQs2RIHZE7Rd73M,103709
29
29
  pyedb/dotnet/edb_core/general.py,sha256=f-WuyJY1nkfMEXm_fvU7poLfIi4axV1ha5Am1_m2eQ0,4572
30
30
  pyedb/dotnet/edb_core/hfss.py,sha256=paHUyp1QtnBHYtswiWEgeaYRvqDT-HdtFG6rmmkD2_w,68815
31
- pyedb/dotnet/edb_core/layout.py,sha256=cz-SxDFhRpSwpCFL7-bz1Yz7ArM6JsLyDKMSVlch-K8,50110
31
+ pyedb/dotnet/edb_core/layout.py,sha256=ywUnsz01JaGqCO2KIKBrv2u76us08EoBzZyWJGmUrwQ,50263
32
32
  pyedb/dotnet/edb_core/layout_validation.py,sha256=_ZcLxePMNauzQxHKWWZGfjuT9tUPS0ZeVKNK7avtJnw,11714
33
33
  pyedb/dotnet/edb_core/materials.py,sha256=9HTDzxraPjAl3Jc7beHQfxe6axQY-tw6hDW1A05O2GM,43426
34
34
  pyedb/dotnet/edb_core/net_class.py,sha256=fAQoXsjn-Ae3gVYnUJO7yGZ6zEDEf_Zx5Mzq_h0UH7k,11582
@@ -87,19 +87,19 @@ pyedb/dotnet/edb_core/geometry/polygon_data.py,sha256=NQxTlbGPLHf2rW8wgHQzpbPf0z
87
87
  pyedb/dotnet/edb_core/sim_setup_data/__init__.py,sha256=8jByHkoaowAYQTCww-zRrTQmN061fLz_OHjTLSrzQQY,58
88
88
  pyedb/dotnet/edb_core/sim_setup_data/data/__init__.py,sha256=8jByHkoaowAYQTCww-zRrTQmN061fLz_OHjTLSrzQQY,58
89
89
  pyedb/dotnet/edb_core/sim_setup_data/data/adaptive_frequency_data.py,sha256=tlHI7PUUoseNnJAtihpjb1PwXYNr-4ztAAnunlLLWVQ,2463
90
- pyedb/dotnet/edb_core/sim_setup_data/data/mesh_operation.py,sha256=tP55JjbCvhJiWNNFbyia4_K43j1IkdRo-YtaaoPz5gU,7919
90
+ pyedb/dotnet/edb_core/sim_setup_data/data/mesh_operation.py,sha256=bWKZTMqROiXvG6T3i7EcapcQBcL0gOChDu4tksdk1xo,8073
91
91
  pyedb/dotnet/edb_core/sim_setup_data/data/settings.py,sha256=u2EhL_netNF4FTQicWysPeXzkFBqBZhFjdwpu4LuBlk,27624
92
92
  pyedb/dotnet/edb_core/sim_setup_data/data/sim_setup_info.py,sha256=dHeyuMm1hRimBx7zrDG0w1q74mIhcUGxk49QoETUq2w,2952
93
93
  pyedb/dotnet/edb_core/sim_setup_data/data/simulation_settings.py,sha256=OmaUj4uhRkhIQgm80eLzuAark8rs5Tx6GrSjvYN74Eo,2549
94
94
  pyedb/dotnet/edb_core/sim_setup_data/data/siw_dc_ir_settings.py,sha256=b7Zpg6nNQArYxvdxlVhXDzvvCSC5sKFvdt10b0MHkvc,8605
95
- pyedb/dotnet/edb_core/sim_setup_data/data/sweep_data.py,sha256=fs9kk5futupQUoG_k4lD9krY89YFHwkc7KTHaTdF2DA,17071
95
+ pyedb/dotnet/edb_core/sim_setup_data/data/sweep_data.py,sha256=YeFy9YoYVaieaBTnoXwzo66LyAOrEb5LnNDKv-FAlh8,17970
96
96
  pyedb/dotnet/edb_core/sim_setup_data/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
97
  pyedb/dotnet/edb_core/sim_setup_data/io/siwave.py,sha256=XOGBUtFuBJ61lsyylmW0mR_FDbnmwJ7s58r36peREhE,31311
98
98
  pyedb/dotnet/edb_core/utilities/__init__.py,sha256=8jByHkoaowAYQTCww-zRrTQmN061fLz_OHjTLSrzQQY,58
99
99
  pyedb/dotnet/edb_core/utilities/heatsink.py,sha256=7G7Yx9TxbL5EAiR51MnhdRiAQBVf-d0hKsXDw5OYX2Q,2220
100
- pyedb/dotnet/edb_core/utilities/hfss_simulation_setup.py,sha256=YJr1k0iRaw3rswcX57YPKCU_kStkLMQkpmrr6FeWBiM,13819
100
+ pyedb/dotnet/edb_core/utilities/hfss_simulation_setup.py,sha256=Uy3w4rRu-c8s0jZ5OqAy_SZl0rPKWff-d_A48wTi3mg,13687
101
101
  pyedb/dotnet/edb_core/utilities/obj_base.py,sha256=lufR0sZj0QfZ2wlNvLL6aM1KVqCNY2A7taPPdWcK20w,3312
102
- pyedb/dotnet/edb_core/utilities/simulation_setup.py,sha256=_yRSgYZRXWZw-uS7fXREIhhT3g4XtJM-trXvWfoYIYc,11594
102
+ pyedb/dotnet/edb_core/utilities/simulation_setup.py,sha256=admZemUDqwOXg7485556MOH3LEMuayZVEtDCzNq0MWM,12299
103
103
  pyedb/dotnet/edb_core/utilities/siwave_simulation_setup.py,sha256=s24jfphD88c1Ru_bN2R-Hl70VdPzusBz7d75oYujtl4,12383
104
104
  pyedb/generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
105
  pyedb/generic/constants.py,sha256=prWLZH0-SeBIVK6LHZ4SGZFQCofuym2TuQYfdqwhuSQ,28956
@@ -173,7 +173,7 @@ pyedb/misc/siw_feature_config/emc/tag_library.py,sha256=yUK4w3hequU017E2DbkA4KE2
173
173
  pyedb/misc/siw_feature_config/emc/xml_generic.py,sha256=55X-V0OxWq-v7FTiDVjaZif8V_2xxsvJlJ8bs9Bf61I,2521
174
174
  pyedb/modeler/geometry_operators.py,sha256=iXNGfp3oMAxc6Ij_jatawR9NAKksMfnmWTaoHQVGX80,72699
175
175
  pyedb/siwave_core/icepak.py,sha256=WnZ-t8mik7LDY06V8hZFV-TxRZJQWK7bu_8Ichx-oBs,5206
176
- pyedb-0.15.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
177
- pyedb-0.15.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
178
- pyedb-0.15.0.dist-info/METADATA,sha256=S2CnVCGVKwvjhyNatAma3o1zlQaEhjaepHEHSZQYBwA,8336
179
- pyedb-0.15.0.dist-info/RECORD,,
176
+ pyedb-0.16.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
177
+ pyedb-0.16.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
178
+ pyedb-0.16.0.dist-info/METADATA,sha256=VG5dbv6_kD6GH-H56A7aGDCQDTcJgMNSJusDxQ8eTo0,8336
179
+ pyedb-0.16.0.dist-info/RECORD,,
File without changes