pyedb 0.2.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 (128) hide show
  1. pyedb/__init__.py +17 -0
  2. pyedb/dotnet/__init__.py +0 -0
  3. pyedb/dotnet/application/Variables.py +2261 -0
  4. pyedb/dotnet/application/__init__.py +0 -0
  5. pyedb/dotnet/clr_module.py +103 -0
  6. pyedb/dotnet/edb.py +4237 -0
  7. pyedb/dotnet/edb_core/__init__.py +1 -0
  8. pyedb/dotnet/edb_core/cell/__init__.py +0 -0
  9. pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
  10. pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
  11. pyedb/dotnet/edb_core/components.py +2669 -0
  12. pyedb/dotnet/edb_core/configuration.py +423 -0
  13. pyedb/dotnet/edb_core/definition/__init__.py +0 -0
  14. pyedb/dotnet/edb_core/definition/component_def.py +166 -0
  15. pyedb/dotnet/edb_core/definition/component_model.py +30 -0
  16. pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
  17. pyedb/dotnet/edb_core/definition/definitions.py +12 -0
  18. pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
  19. pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
  20. pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
  21. pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
  22. pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
  23. pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
  24. pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
  25. pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
  26. pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
  27. pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
  28. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
  29. pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
  30. pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
  31. pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
  32. pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
  33. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
  34. pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
  35. pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
  36. pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
  37. pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
  38. pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
  39. pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
  40. pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
  41. pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
  42. pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
  43. pyedb/dotnet/edb_core/general.py +181 -0
  44. pyedb/dotnet/edb_core/hfss.py +1646 -0
  45. pyedb/dotnet/edb_core/layout.py +1244 -0
  46. pyedb/dotnet/edb_core/layout_validation.py +272 -0
  47. pyedb/dotnet/edb_core/materials.py +939 -0
  48. pyedb/dotnet/edb_core/net_class.py +335 -0
  49. pyedb/dotnet/edb_core/nets.py +1215 -0
  50. pyedb/dotnet/edb_core/padstack.py +1389 -0
  51. pyedb/dotnet/edb_core/siwave.py +1427 -0
  52. pyedb/dotnet/edb_core/stackup.py +2703 -0
  53. pyedb/edb_logger.py +396 -0
  54. pyedb/generic/__init__.py +0 -0
  55. pyedb/generic/constants.py +1063 -0
  56. pyedb/generic/data_handlers.py +320 -0
  57. pyedb/generic/design_types.py +104 -0
  58. pyedb/generic/filesystem.py +150 -0
  59. pyedb/generic/general_methods.py +1535 -0
  60. pyedb/generic/plot.py +1840 -0
  61. pyedb/generic/process.py +285 -0
  62. pyedb/generic/settings.py +224 -0
  63. pyedb/ipc2581/__init__.py +0 -0
  64. pyedb/ipc2581/bom/__init__.py +0 -0
  65. pyedb/ipc2581/bom/bom.py +21 -0
  66. pyedb/ipc2581/bom/bom_item.py +32 -0
  67. pyedb/ipc2581/bom/characteristics.py +37 -0
  68. pyedb/ipc2581/bom/refdes.py +16 -0
  69. pyedb/ipc2581/content/__init__.py +0 -0
  70. pyedb/ipc2581/content/color.py +38 -0
  71. pyedb/ipc2581/content/content.py +55 -0
  72. pyedb/ipc2581/content/dictionary_color.py +29 -0
  73. pyedb/ipc2581/content/dictionary_fill.py +28 -0
  74. pyedb/ipc2581/content/dictionary_line.py +30 -0
  75. pyedb/ipc2581/content/entry_color.py +13 -0
  76. pyedb/ipc2581/content/entry_line.py +14 -0
  77. pyedb/ipc2581/content/fill.py +15 -0
  78. pyedb/ipc2581/content/layer_ref.py +10 -0
  79. pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
  80. pyedb/ipc2581/ecad/__init__.py +0 -0
  81. pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
  82. pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
  83. pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
  84. pyedb/ipc2581/ecad/cad_data/component.py +41 -0
  85. pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
  86. pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
  87. pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
  88. pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
  89. pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
  90. pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
  91. pyedb/ipc2581/ecad/cad_data/package.py +104 -0
  92. pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
  93. pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
  94. pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
  95. pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
  96. pyedb/ipc2581/ecad/cad_data/path.py +89 -0
  97. pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
  98. pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
  99. pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
  100. pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
  101. pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
  102. pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
  103. pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
  104. pyedb/ipc2581/ecad/cad_data/step.py +275 -0
  105. pyedb/ipc2581/ecad/cad_header.py +33 -0
  106. pyedb/ipc2581/ecad/ecad.py +19 -0
  107. pyedb/ipc2581/ecad/spec.py +46 -0
  108. pyedb/ipc2581/history_record.py +37 -0
  109. pyedb/ipc2581/ipc2581.py +387 -0
  110. pyedb/ipc2581/logistic_header.py +25 -0
  111. pyedb/misc/__init__.py +0 -0
  112. pyedb/misc/aedtlib_personalib_install.py +14 -0
  113. pyedb/misc/downloads.py +322 -0
  114. pyedb/misc/misc.py +67 -0
  115. pyedb/misc/pyedb.runtimeconfig.json +13 -0
  116. pyedb/misc/siw_feature_config/__init__.py +0 -0
  117. pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
  118. pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
  119. pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
  120. pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
  121. pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
  122. pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
  123. pyedb/misc/utilities.py +27 -0
  124. pyedb/modeler/geometry_operators.py +2082 -0
  125. pyedb-0.2.0.dist-info/LICENSE +21 -0
  126. pyedb-0.2.0.dist-info/METADATA +208 -0
  127. pyedb-0.2.0.dist-info/RECORD +128 -0
  128. pyedb-0.2.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,423 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+ from pyedb.generic.general_methods import pyedb_function_handler
5
+
6
+
7
+ def load_json(config_file):
8
+ if isinstance(config_file, (str, Path)):
9
+ with open(config_file, "r") as f:
10
+ return json.load(f)
11
+ elif isinstance(config_file, dict):
12
+ return config_file
13
+
14
+
15
+ class Configuration:
16
+ """Enables export and import of a JSON configuration file that can be applied to a new or existing design."""
17
+
18
+ def __init__(self, pedb):
19
+ self._pedb = pedb
20
+ self._components = self._pedb.components.components
21
+ self.data = {}
22
+
23
+ @pyedb_function_handler
24
+ def load(self, config_file, append=True, apply_file=False, output_file=None, open_at_the_end=True):
25
+ """Import configuration settings from a JSON file.
26
+
27
+ Parameters
28
+ ----------
29
+ config_file : str
30
+ Full path to json file.
31
+ append : bool, optional
32
+ Whether if the new file will append to existing properties or the properties will be cleared before import.
33
+ Default is ``True`` to keep stored properties
34
+ apply_file : bool, optional
35
+ Whether to apply the file after the load or not. Default is ``False``.
36
+ output_file : str, optional
37
+ Full path to the new aedb folder where the configured project will be saved.
38
+ open_at_the_end : bool, optional
39
+ Whether to keep the new generated file opened at the end. Default is ``True``.
40
+
41
+ Returns
42
+ -------
43
+ dict
44
+ Config dictionary.
45
+ """
46
+
47
+ data = load_json(config_file)
48
+ if not append:
49
+ self.data = {}
50
+ for k, v in data.items():
51
+ self.data[k] = v
52
+ if apply_file:
53
+ original_file = self._pedb.edbpath
54
+ if output_file:
55
+ self._pedb.save_edb_as(output_file)
56
+ self.run()
57
+ if output_file and not open_at_the_end:
58
+ self._pedb.save_edb()
59
+ self._pedb.close_edb()
60
+ self._pedb.edbpath = original_file
61
+ self._pedb.open_edb()
62
+ return self.data
63
+
64
+ @pyedb_function_handler()
65
+ def run(self):
66
+ """Apply configuration settings to the current design"""
67
+
68
+ # Configure components
69
+ if not self.data:
70
+ self._pedb.logger.error("No data loaded. Please load a configuration file.")
71
+ return False
72
+
73
+ if "components" in self.data:
74
+ self._load_components()
75
+
76
+ # Configure ports
77
+ if "ports" in self.data:
78
+ self._load_ports()
79
+
80
+ # Configure sources
81
+ if "sources" in self.data:
82
+ self._load_sources()
83
+
84
+ # Configure HFSS setup
85
+ if "setups" in self.data:
86
+ self._load_setups()
87
+
88
+ # Configure stackup
89
+ if "stackup" in self.data:
90
+ self._load_stackup()
91
+
92
+ # Configure S-parameter
93
+ if "s_parameters" in self.data:
94
+ self._load_s_parameter()
95
+
96
+ return True
97
+
98
+
99
+ @pyedb_function_handler
100
+ def _load_components(self):
101
+ """Imports component information from json."""
102
+
103
+ for comp in self.data["components"] :
104
+ refdes = comp["reference_designator"]
105
+ part_type = comp["part_type"].lower()
106
+ if part_type == "resistor":
107
+ part_type = "Resistor"
108
+ elif part_type == "capacitor":
109
+ part_type = "Capacitor"
110
+ elif part_type == "inductor":
111
+ part_type = "Inductor"
112
+ elif part_type == "io":
113
+ part_type = "IO"
114
+ elif part_type == "ic":
115
+ part_type = "IC"
116
+ else:
117
+ part_type = "Other"
118
+
119
+ comp_layout = self._components[refdes]
120
+ comp_layout.type = part_type
121
+
122
+ if part_type in ["Resistor", "Capacitor", "Inductor"]:
123
+ comp_layout.is_enabled = comp["enabled"]
124
+ rlc_model = comp["rlc_model"] if "rlc_model" in comp else None
125
+ # n_port_model = comp["NPortModel"] if "NPortModel" in comp else None
126
+ # netlist_model = comp["NetlistModel"] if "NetlistModel" in comp else None
127
+ # spice_model = comp["SpiceModel"] if "SpiceModel" in comp else None
128
+
129
+ if rlc_model:
130
+ model_layout = comp_layout.model
131
+
132
+ pin_pairs = rlc_model["pin_pairs"] if "pin_pairs" in rlc_model else None
133
+ if pin_pairs:
134
+ for pp in model_layout.pin_pairs:
135
+ model_layout.delete_pin_pair_rlc(pp)
136
+
137
+ for pp in pin_pairs:
138
+ rlc_model_type = pp["type"]
139
+ p1 = pp["p1"]
140
+ p2 = pp["p2"]
141
+
142
+ r = pp["resistance"] if "resistance" in pp else None
143
+ l = pp["inductance"] if "inductance" in pp else None
144
+ c = pp["capacitance"] if "capacitance" in pp else None
145
+
146
+ pin_pair = self._pedb.edb_api.utility.PinPair(p1, p2)
147
+ rlc = self._pedb.edb_api.utility.Rlc()
148
+
149
+ rlc.IsParallel = False if rlc_model_type == "series" else True
150
+ if not r is None:
151
+ rlc.REnabled = True
152
+ rlc.R = self._pedb.edb_value(r)
153
+ else:
154
+ rlc.REnabled = False
155
+
156
+ if not l is None:
157
+ rlc.LEnabled = True
158
+ rlc.L = self._pedb.edb_value(l)
159
+ else:
160
+ rlc.LEnabled = False
161
+
162
+ if not c is None:
163
+ rlc.CEnabled = True
164
+ rlc.C = self._pedb.edb_value(c)
165
+ else:
166
+ rlc.CEnabled = False
167
+
168
+ model_layout._set_pin_pair_rlc(pin_pair, rlc)
169
+ comp_layout.model = model_layout
170
+
171
+ # Configure port properties
172
+ port_properties = comp["port_properties"] if "port_properties" in comp else None
173
+ if port_properties:
174
+ ref_offset = port_properties["reference_offset"]
175
+ ref_size_auto = port_properties["reference_size_auto"]
176
+ ref_size_x = port_properties["reference_size_x"]
177
+ ref_size_y = port_properties["reference_size_y"]
178
+ else:
179
+ ref_offset = 0
180
+ ref_size_auto = True
181
+ ref_size_x = 0
182
+ ref_size_y = 0
183
+
184
+ # Configure solder ball properties
185
+ solder_ball_properties = comp["solder_ball_properties"] if "solder_ball_properties" in comp else None
186
+ if solder_ball_properties:
187
+ shape = solder_ball_properties["shape"]
188
+ diameter = solder_ball_properties["diameter"]
189
+ mid_diameter = (
190
+ solder_ball_properties["mid_diameter"] if "mid_diameter" in solder_ball_properties else diameter
191
+ )
192
+ height = solder_ball_properties["height"]
193
+
194
+ self._pedb.components.set_solder_ball(
195
+ component=refdes,
196
+ sball_diam=diameter,
197
+ sball_mid_diam=mid_diameter,
198
+ sball_height=height,
199
+ shape=shape,
200
+ auto_reference_size=ref_size_auto,
201
+ reference_height=ref_offset,
202
+ reference_size_x=ref_size_x,
203
+ reference_size_y=ref_size_y,
204
+ )
205
+
206
+ @pyedb_function_handler
207
+ def _load_ports(self):
208
+ """Imports port information from json."""
209
+ for port in self.data["ports"]:
210
+ port_type = port["type"]
211
+ refdes = port["reference_designator"]
212
+ comp_layout = self._components[refdes]
213
+ pos = port["from"]
214
+ if "pin" in pos:
215
+ pin_name = pos["pin"]
216
+ port_name = "{}_{}".format(refdes, pin_name)
217
+ pos_terminal = comp_layout.pins[pin_name].get_terminal(port_name, True)
218
+ else: # Net
219
+ net_name = pos["net"]
220
+ port_name = "{}_{}".format(refdes, net_name)
221
+ if port_type == "circuit":
222
+ pg_name = "pg_{}".format(port_name)
223
+ _, pg = self._pedb.siwave.create_pin_group_on_net(refdes, net_name, pg_name)
224
+ pos_terminal = pg.get_terminal(port_name, True)
225
+ else: # Coax port
226
+ for _, p in comp_layout.pins.items():
227
+ if p.net_name == net_name:
228
+ pos_terminal = p.get_terminal(port_name, True)
229
+ break
230
+
231
+ if port_type == "circuit":
232
+ neg = port["to"]
233
+ if "pin" in neg:
234
+ pin_name = neg["pin"]
235
+ port_name = "{}_{}_ref".format(refdes, pin_name)
236
+ neg_terminal = comp_layout.pins[pin_name].get_terminal(port_name, True)
237
+ else:
238
+ net_name = neg["net"]
239
+ port_name = "{}_{}_ref".format(refdes, net_name)
240
+ pg_name = "pg_{}".format(port_name)
241
+ if pg_name not in self._pedb.siwave.pin_groups:
242
+ _, pg = self._pedb.siwave.create_pin_group_on_net(refdes, net_name, pg_name)
243
+ else:
244
+ pg = self._pedb.siwave.pin_groups[pg_name]
245
+ neg_terminal = pg.get_terminal(port_name, True)
246
+
247
+ self._pedb.create_port(pos_terminal, neg_terminal, True)
248
+ else:
249
+ self._pedb.create_port(pos_terminal)
250
+
251
+ @pyedb_function_handler
252
+ def _load_sources(self):
253
+ """Imports source information from json."""
254
+
255
+ for src in self.data["sources"]:
256
+ src_type = src["type"]
257
+ refdes = src["reference_designator"]
258
+ name = src["name"]
259
+ comp_layout = self._components[refdes]
260
+
261
+ pos = src["from"]
262
+ if "pin" in pos:
263
+ pin_name = pos["pin"]
264
+ src_name = name
265
+ pos_terminal = comp_layout.pins[pin_name].get_terminal(src_name, True)
266
+ elif "net" in pos: # Net
267
+ net_name = pos["net"]
268
+ src_name = "{}_{}".format(refdes, net_name)
269
+ pg_name = "pg_{}".format(src_name)
270
+ _, pg = self._pedb.siwave.create_pin_group_on_net(refdes, net_name, pg_name)
271
+ pos_terminal = pg.get_terminal(src_name, True)
272
+
273
+ neg = src["to"]
274
+ if "pin" in neg:
275
+ pin_name = neg["pin"]
276
+ src_name = name + "_ref"
277
+ neg_terminal = comp_layout.pins[pin_name].get_terminal(src_name, True)
278
+ elif "net" in neg:
279
+ net_name = neg["net"]
280
+ src_name = name + "_ref"
281
+ pg_name = "pg_{}".format(src_name)
282
+ if pg_name not in self._pedb.siwave.pin_groups:
283
+ _, pg = self._pedb.siwave.create_pin_group_on_net(refdes, net_name, pg_name)
284
+ else: # pragma no cover
285
+ pg = self._pedb.siwave.pin_groups[pg_name]
286
+ neg_terminal = pg.get_terminal(src_name, True)
287
+
288
+ if src_type == "voltage":
289
+ src_obj = self._pedb.create_voltage_source(pos_terminal, neg_terminal)
290
+ src_obj.magnitude = src["magnitude"]
291
+ elif src_type == "current":
292
+ src_obj = self._pedb.create_current_source(pos_terminal, neg_terminal)
293
+ src_obj.magnitude = src["magnitude"]
294
+
295
+ @pyedb_function_handler
296
+ def _load_setups(self):
297
+ """Imports setup information from json."""
298
+ for setup in self.data["setups"]:
299
+ setup_type = setup["type"]
300
+
301
+ edb_setup = None
302
+ name = setup["name"]
303
+
304
+ if setup_type.lower() == "siwave_dc":
305
+ if name not in self._pedb.setups:
306
+ self._pedb.logger.info("Setup {} created.".format(name))
307
+ edb_setup = self._pedb.create_siwave_dc_setup(name)
308
+ else:
309
+ self._pedb.logger.warning("Setup {} already existing. Editing it.".format(name))
310
+ edb_setup = self._pedb.setups[name]
311
+ edb_setup.set_dc_slider(setup["dc_slider_position"])
312
+ else:
313
+ if setup_type.lower() == "hfss":
314
+ if name not in self._pedb.setups:
315
+ self._pedb.logger.info("Setup {} created.".format(name))
316
+ edb_setup = self._pedb.create_hfss_setup(name)
317
+ else:
318
+ self._pedb.logger.warning("Setup {} already existing. Editing it.".format(name))
319
+ edb_setup = self._pedb.setups[name]
320
+ edb_setup.set_solution_single_frequency(
321
+ setup["f_adapt"], max_num_passes=setup["max_num_passes"], max_delta_s=setup["max_mag_delta_s"]
322
+ )
323
+ elif setup_type.lower() == "siwave_syz":
324
+ name = setup["name"]
325
+ if name not in self._pedb.setups:
326
+ self._pedb.logger.info("Setup {} created.".format(name))
327
+ edb_setup = self._pedb.create_siwave_syz_setup(name)
328
+ else:
329
+ self._pedb.logger.warning("Setup {} already existing. Editing it.".format(name))
330
+ edb_setup = self._pedb.setups[name]
331
+ edb_setup.si_slider_position = setup["si_slider_position"]
332
+
333
+ if "freq_sweep" in setup:
334
+ for fsweep in setup["freq_sweep"]:
335
+ frequencies = fsweep["frequencies"]
336
+ freqs = []
337
+
338
+ for d in frequencies:
339
+ if d["distribution"] == "linear step":
340
+ freqs.append(
341
+ [
342
+ "linear scale",
343
+ self._pedb.edb_value(d["start"]).ToString(),
344
+ self._pedb.edb_value(d["stop"]).ToString(),
345
+ self._pedb.edb_value(d["step"]).ToString(),
346
+ ]
347
+ )
348
+ elif d["distribution"] == "linear count":
349
+ freqs.append(
350
+ [
351
+ "linear count",
352
+ self._pedb.edb_value(d["start"]).ToString(),
353
+ self._pedb.edb_value(d["stop"]).ToString(),
354
+ int(d["points"]),
355
+ ]
356
+ )
357
+ elif d["distribution"] == "log scale":
358
+ freqs.append(
359
+ [
360
+ "log scale",
361
+ self._pedb.edb_value(d["start"]).ToString(),
362
+ self._pedb.edb_value(d["stop"]).ToString(),
363
+ int(d["samples"]),
364
+ ]
365
+ )
366
+
367
+ edb_setup.add_frequency_sweep(
368
+ fsweep["name"],
369
+ frequency_sweep=freqs,
370
+ )
371
+
372
+ @pyedb_function_handler
373
+ def _load_stackup(self):
374
+ """Imports stackup information from json."""
375
+ data = self.data["stackup"]
376
+ materials = data["materials"] if "materials" in data else []
377
+ materials_reformatted = {}
378
+ for mat in materials:
379
+ new_mat = {}
380
+ new_mat["name"] = mat["name"]
381
+ if "conductivity" in mat:
382
+ new_mat["conductivity"] = mat["conductivity"]
383
+ if "permittivity" in mat:
384
+ new_mat["permittivity"] = mat["permittivity"]
385
+ if "dielectricLoss_tangent" in mat:
386
+ new_mat["loss_tangent"] = mat["dielectricLoss_tangent"]
387
+
388
+ materials_reformatted[mat["name"]] = new_mat
389
+
390
+ layers = data["layers"]
391
+ layers_reformatted = {}
392
+
393
+ for l in layers:
394
+ lyr = {
395
+ "name": l["name"],
396
+ "type": l["type"],
397
+ "material": l["material"],
398
+ "thickness": l["thickness"],
399
+ }
400
+ if "fill_material" in l:
401
+ lyr["dielectric_fill"] = l["fill_material"]
402
+ layers_reformatted[l["name"]] = lyr
403
+ stackup_reformated = {"layers": layers_reformatted, "materials": materials_reformatted}
404
+ self._pedb.stackup.load(stackup_reformated)
405
+
406
+ @pyedb_function_handler
407
+ def _load_s_parameter(self):
408
+ """Imports s-parameter information from json."""
409
+
410
+ for sp in self.data["s_parameters"]:
411
+ fpath = sp["file_path"]
412
+ sp_name = sp["name"]
413
+ comp_def_name = sp["component_definition"]
414
+ comp_def = self._pedb.definitions.component[comp_def_name]
415
+ comp_def.add_n_port_model(fpath, sp_name)
416
+ if sp["apply_to_all"]:
417
+ for refdes, comp in comp_def.components.items():
418
+ if refdes not in sp["components"]:
419
+ comp.use_s_parameter_model(sp_name)
420
+ else:
421
+ for refdes, comp in comp_def.components.items():
422
+ if refdes in sp["components"]:
423
+ comp.use_s_parameter_model(sp_name)
File without changes
@@ -0,0 +1,166 @@
1
+ import os
2
+
3
+ from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
4
+ from pyedb.generic.general_methods import pyedb_function_handler
5
+ from pyedb.dotnet.edb_core.definition.component_model import (
6
+ NPortComponentModel
7
+ )
8
+
9
+
10
+ class EDBComponentDef(ObjBase):
11
+ """Manages EDB functionalities for component definitions.
12
+
13
+ Parameters
14
+ ----------
15
+ parent : :class:`pyedb.dotnet.edb_core.components.Components`
16
+ Inherited AEDT object.
17
+ comp_def : object
18
+ Edb ComponentDef Object
19
+ """
20
+
21
+ def __init__(self, pedb, edb_object=None):
22
+ super().__init__(pedb, edb_object)
23
+ self._pedb = pedb
24
+
25
+ @property
26
+ def _comp_model(self):
27
+ return list(self._edb_object.GetComponentModels()) # pragma: no cover
28
+
29
+ @property
30
+ def part_name(self):
31
+ """Retrieve component definition name."""
32
+ return self._edb_object.GetName()
33
+
34
+ @part_name.setter
35
+ def part_name(self, name):
36
+ self._edb_object.SetName(name)
37
+
38
+ @property
39
+ def type(self):
40
+ """Retrieve the component definition type.
41
+
42
+ Returns
43
+ -------
44
+ str
45
+ """
46
+ num = len(set(comp.type for refdes, comp in self.components.items()))
47
+ if num == 0: # pragma: no cover
48
+ return None
49
+ elif num == 1:
50
+ return list(self.components.values())[0].type
51
+ else:
52
+ return "mixed" # pragma: no cover
53
+
54
+ @type.setter
55
+ def type(self, value):
56
+ for comp in list(self.components.values()):
57
+ comp.type = value
58
+
59
+ @property
60
+ def components(self):
61
+ """Get the list of components belonging to this component definition.
62
+
63
+ Returns
64
+ -------
65
+ dict of :class:`EDBComponent`
66
+ """
67
+ from pyedb.dotnet.edb_core.edb_data.components_data import EDBComponent
68
+ comp_list = [
69
+ EDBComponent(self._pedb, l)
70
+ for l in self._pedb.edb_api.cell.hierarchy.component.FindByComponentDef(
71
+ self._pedb.active_layout, self.part_name
72
+ )
73
+ ]
74
+ return {comp.refdes: comp for comp in comp_list}
75
+
76
+ @pyedb_function_handler()
77
+ def assign_rlc_model(self, res=None, ind=None, cap=None, is_parallel=False):
78
+ """Assign RLC to all components under this part name.
79
+
80
+ Parameters
81
+ ----------
82
+ res : int, float
83
+ Resistance. Default is ``None``.
84
+ ind : int, float
85
+ Inductance. Default is ``None``.
86
+ cap : int, float
87
+ Capacitance. Default is ``None``.
88
+ is_parallel : bool, optional
89
+ Whether it is parallel or series RLC component.
90
+ """
91
+ for comp in list(self.components.values()):
92
+ res, ind, cap = res, ind, cap
93
+ comp.assign_rlc_model(res, ind, cap, is_parallel)
94
+ return True
95
+
96
+ @pyedb_function_handler()
97
+ def assign_s_param_model(self, file_path, model_name=None, reference_net=None):
98
+ """Assign S-parameter to all components under this part name.
99
+
100
+ Parameters
101
+ ----------
102
+ file_path : str
103
+ File path of the S-parameter model.
104
+ name : str, optional
105
+ Name of the S-parameter model.
106
+
107
+ Returns
108
+ -------
109
+
110
+ """
111
+ for comp in list(self.components.values()):
112
+ comp.assign_s_param_model(file_path, model_name, reference_net)
113
+ return True
114
+
115
+ @pyedb_function_handler()
116
+ def assign_spice_model(self, file_path, model_name=None):
117
+ """Assign Spice model to all components under this part name.
118
+
119
+ Parameters
120
+ ----------
121
+ file_path : str
122
+ File path of the Spice model.
123
+ name : str, optional
124
+ Name of the Spice model.
125
+
126
+ Returns
127
+ -------
128
+
129
+ """
130
+ for comp in list(self.components.values()):
131
+ comp.assign_spice_model(file_path, model_name)
132
+ return True
133
+
134
+ @property
135
+ def component_models(self):
136
+ temp = {}
137
+ for i in list(self._edb_object.GetComponentModels()):
138
+ temp_type = i.ToString().split(".")[0]
139
+ if temp_type == "NPortComponentModel":
140
+ edb_object = NPortComponentModel(self._pedb, i)
141
+ temp[edb_object.name] = edb_object
142
+ return temp
143
+
144
+ @pyedb_function_handler
145
+ def _add_component_model(self, value):
146
+ self._edb_object.AddComponentModel(value._edb_object)
147
+
148
+ @pyedb_function_handler
149
+ def add_n_port_model(self, fpath, name=None):
150
+ if not name:
151
+ name = os.path.splitext(os.path.basename(fpath)[0])
152
+
153
+ from pyedb.dotnet.edb_core.definition.component_model import NPortComponentModel
154
+
155
+ edb_object = self._pedb.definition.NPortComponentModel.Create(name)
156
+ n_port_comp_model = NPortComponentModel(self._pedb, edb_object)
157
+ n_port_comp_model.reference_file = fpath
158
+
159
+ self._add_component_model(n_port_comp_model)
160
+
161
+ @pyedb_function_handler
162
+ def create(self, name):
163
+ cell_type = self._pedb.edb_api.cell.CellType.FootprintCell
164
+ footprint_cell = self._pedb._active_cell.cell.Create(self._pedb.active_db, cell_type, name)
165
+ edb_object = self._pedb.edb_api.definition.ComponentDef.Create(self._pedb.active_db, name, footprint_cell)
166
+ return EDBComponentDef(self._pedb, edb_object)
@@ -0,0 +1,30 @@
1
+ from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
2
+ from pyedb.generic.general_methods import pyedb_function_handler
3
+
4
+
5
+ class ComponentModel(ObjBase):
6
+ """Manages component model class."""
7
+
8
+ def __init__(self, pedb, edb_object):
9
+ super().__init__(pedb, edb_object)
10
+ self._model_type_mapping = {"PinPairModel": self._pedb.edb_api.cell}
11
+
12
+ @pyedb_function_handler()
13
+ def name(self):
14
+ """Name of the component model."""
15
+ return self._edb_object.GetName()
16
+
17
+
18
+ class NPortComponentModel(ComponentModel):
19
+ """Class for n-port component models."""
20
+
21
+ def __init__(self, pedb, edb_object):
22
+ super().__init__(pedb, edb_object)
23
+
24
+ @property
25
+ def reference_file(self):
26
+ return self._edb_object.GetReferenceFile()
27
+
28
+ @reference_file.setter
29
+ def reference_file(self, value):
30
+ self._edb_object.SetReferenceFile(value)
@@ -0,0 +1,18 @@
1
+ from pyedb.dotnet.edb_core.edb_data.obj_base import ObjBase
2
+ from pyedb.generic.general_methods import pyedb_function_handler
3
+
4
+
5
+ class DefinitionObj(ObjBase):
6
+ """Base class for definition objects."""
7
+
8
+ def __init__(self, pedb, edb_object):
9
+ super().__init__(pedb, edb_object)
10
+
11
+ @property
12
+ def definition_obj_type(self):
13
+ return self._edb_object.GetDefinitionObjType()
14
+
15
+ @property
16
+ def name(self):
17
+ return self._edb_object.GetName()
18
+
@@ -0,0 +1,12 @@
1
+ import os
2
+ from pyedb.dotnet.edb_core.definition.component_def import EDBComponentDef
3
+
4
+
5
+ class Definitions:
6
+ def __init__(self, pedb):
7
+ self._pedb = pedb
8
+
9
+ @property
10
+ def component(self):
11
+ """Component definitions"""
12
+ return {l.GetName(): EDBComponentDef(self._pedb, l) for l in list(self._pedb.active_db.ComponentDefs)}
File without changes