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.
- pyedb/__init__.py +17 -0
- pyedb/dotnet/__init__.py +0 -0
- pyedb/dotnet/application/Variables.py +2261 -0
- pyedb/dotnet/application/__init__.py +0 -0
- pyedb/dotnet/clr_module.py +103 -0
- pyedb/dotnet/edb.py +4237 -0
- pyedb/dotnet/edb_core/__init__.py +1 -0
- pyedb/dotnet/edb_core/cell/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
- pyedb/dotnet/edb_core/components.py +2669 -0
- pyedb/dotnet/edb_core/configuration.py +423 -0
- pyedb/dotnet/edb_core/definition/__init__.py +0 -0
- pyedb/dotnet/edb_core/definition/component_def.py +166 -0
- pyedb/dotnet/edb_core/definition/component_model.py +30 -0
- pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
- pyedb/dotnet/edb_core/definition/definitions.py +12 -0
- pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
- pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
- pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
- pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
- pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
- pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
- pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
- pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
- pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
- pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
- pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
- pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
- pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
- pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
- pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
- pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
- pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
- pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
- pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
- pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
- pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
- pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
- pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
- pyedb/dotnet/edb_core/general.py +181 -0
- pyedb/dotnet/edb_core/hfss.py +1646 -0
- pyedb/dotnet/edb_core/layout.py +1244 -0
- pyedb/dotnet/edb_core/layout_validation.py +272 -0
- pyedb/dotnet/edb_core/materials.py +939 -0
- pyedb/dotnet/edb_core/net_class.py +335 -0
- pyedb/dotnet/edb_core/nets.py +1215 -0
- pyedb/dotnet/edb_core/padstack.py +1389 -0
- pyedb/dotnet/edb_core/siwave.py +1427 -0
- pyedb/dotnet/edb_core/stackup.py +2703 -0
- pyedb/edb_logger.py +396 -0
- pyedb/generic/__init__.py +0 -0
- pyedb/generic/constants.py +1063 -0
- pyedb/generic/data_handlers.py +320 -0
- pyedb/generic/design_types.py +104 -0
- pyedb/generic/filesystem.py +150 -0
- pyedb/generic/general_methods.py +1535 -0
- pyedb/generic/plot.py +1840 -0
- pyedb/generic/process.py +285 -0
- pyedb/generic/settings.py +224 -0
- pyedb/ipc2581/__init__.py +0 -0
- pyedb/ipc2581/bom/__init__.py +0 -0
- pyedb/ipc2581/bom/bom.py +21 -0
- pyedb/ipc2581/bom/bom_item.py +32 -0
- pyedb/ipc2581/bom/characteristics.py +37 -0
- pyedb/ipc2581/bom/refdes.py +16 -0
- pyedb/ipc2581/content/__init__.py +0 -0
- pyedb/ipc2581/content/color.py +38 -0
- pyedb/ipc2581/content/content.py +55 -0
- pyedb/ipc2581/content/dictionary_color.py +29 -0
- pyedb/ipc2581/content/dictionary_fill.py +28 -0
- pyedb/ipc2581/content/dictionary_line.py +30 -0
- pyedb/ipc2581/content/entry_color.py +13 -0
- pyedb/ipc2581/content/entry_line.py +14 -0
- pyedb/ipc2581/content/fill.py +15 -0
- pyedb/ipc2581/content/layer_ref.py +10 -0
- pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
- pyedb/ipc2581/ecad/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
- pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
- pyedb/ipc2581/ecad/cad_data/component.py +41 -0
- pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
- pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
- pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
- pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
- pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
- pyedb/ipc2581/ecad/cad_data/package.py +104 -0
- pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
- pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
- pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
- pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
- pyedb/ipc2581/ecad/cad_data/path.py +89 -0
- pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
- pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
- pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
- pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
- pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
- pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
- pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
- pyedb/ipc2581/ecad/cad_data/step.py +275 -0
- pyedb/ipc2581/ecad/cad_header.py +33 -0
- pyedb/ipc2581/ecad/ecad.py +19 -0
- pyedb/ipc2581/ecad/spec.py +46 -0
- pyedb/ipc2581/history_record.py +37 -0
- pyedb/ipc2581/ipc2581.py +387 -0
- pyedb/ipc2581/logistic_header.py +25 -0
- pyedb/misc/__init__.py +0 -0
- pyedb/misc/aedtlib_personalib_install.py +14 -0
- pyedb/misc/downloads.py +322 -0
- pyedb/misc/misc.py +67 -0
- pyedb/misc/pyedb.runtimeconfig.json +13 -0
- pyedb/misc/siw_feature_config/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
- pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
- pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
- pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
- pyedb/misc/utilities.py +27 -0
- pyedb/modeler/geometry_operators.py +2082 -0
- pyedb-0.2.0.dist-info/LICENSE +21 -0
- pyedb-0.2.0.dist-info/METADATA +208 -0
- pyedb-0.2.0.dist-info/RECORD +128 -0
- pyedb-0.2.0.dist-info/WHEEL +4 -0
pyedb/generic/process.py
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import os.path
|
|
2
|
+
|
|
3
|
+
from pyedb.generic.general_methods import env_path, is_ironpython, is_linux
|
|
4
|
+
|
|
5
|
+
if is_linux and is_ironpython:
|
|
6
|
+
import subprocessdotnet as subprocess
|
|
7
|
+
else:
|
|
8
|
+
import subprocess
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SiwaveSolve(object):
|
|
12
|
+
def __init__(self, aedb_path="", aedt_version="2021.2", aedt_installer_path=None):
|
|
13
|
+
self._project_path = aedb_path
|
|
14
|
+
self._exec_path = ""
|
|
15
|
+
self._nbcores = 4
|
|
16
|
+
self._ng = True
|
|
17
|
+
if aedt_installer_path:
|
|
18
|
+
self.installer_path = aedt_installer_path
|
|
19
|
+
else:
|
|
20
|
+
try:
|
|
21
|
+
self.installer_path = env_path(aedt_version)
|
|
22
|
+
except:
|
|
23
|
+
raise Exception("Either a valid aedt version or full path has to be provided")
|
|
24
|
+
if self._ng:
|
|
25
|
+
executable = "siwave_ng"
|
|
26
|
+
else:
|
|
27
|
+
executable = "siwave"
|
|
28
|
+
if is_linux:
|
|
29
|
+
self._exe = os.path.join(self.installer_path, executable)
|
|
30
|
+
else:
|
|
31
|
+
self._exe = os.path.join(self.installer_path, executable + ".exe")
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def siwave_exe(self):
|
|
35
|
+
return self._exe
|
|
36
|
+
|
|
37
|
+
@siwave_exe.setter
|
|
38
|
+
def siwave_exe(self, value):
|
|
39
|
+
self._exe = value
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def projectpath(self):
|
|
43
|
+
return self._project_path
|
|
44
|
+
|
|
45
|
+
@projectpath.setter
|
|
46
|
+
def projectpath(self, value):
|
|
47
|
+
self._project_path = value
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def execfile(self):
|
|
51
|
+
return self._exec_path
|
|
52
|
+
|
|
53
|
+
@execfile.setter
|
|
54
|
+
def execfile(self, value):
|
|
55
|
+
self._exec_path = value
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def nbcores(self):
|
|
59
|
+
return self._nbcores
|
|
60
|
+
|
|
61
|
+
@nbcores.setter
|
|
62
|
+
def nbcores(self, value):
|
|
63
|
+
self._nbcores = value
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def nongraphical(self):
|
|
67
|
+
return self._ng
|
|
68
|
+
|
|
69
|
+
@nongraphical.setter
|
|
70
|
+
def nongraphical(self, value):
|
|
71
|
+
self._ng = value
|
|
72
|
+
|
|
73
|
+
def solve(self):
|
|
74
|
+
# supporting non graphical solve only
|
|
75
|
+
if self.nongraphical:
|
|
76
|
+
if is_linux:
|
|
77
|
+
exe_path = os.path.join(self.installer_path, "siwave_ng")
|
|
78
|
+
else:
|
|
79
|
+
exe_path = os.path.join(self.installer_path, "siwave_ng.exe")
|
|
80
|
+
exec_file = os.path.splitext(self._project_path)[0] + ".exec"
|
|
81
|
+
if os.path.exists(exec_file):
|
|
82
|
+
with open(exec_file, "r+") as f:
|
|
83
|
+
content = f.readlines()
|
|
84
|
+
if "SetNumCpus" not in content:
|
|
85
|
+
f.writelines(str.format("SetNumCpus {}", str(self.nbcores)) + "\n")
|
|
86
|
+
f.writelines("SaveSiw")
|
|
87
|
+
else:
|
|
88
|
+
fstarts = [i for i in range(len(content)) if content[i].startswith("SetNumCpus")]
|
|
89
|
+
content[fstarts[0]] = str.format("SetNumCpus {}", str(self.nbcores))
|
|
90
|
+
f.close()
|
|
91
|
+
os.remove(exec_file)
|
|
92
|
+
f = open(exec_file, "w")
|
|
93
|
+
f.writelines(content)
|
|
94
|
+
command = [exe_path]
|
|
95
|
+
command.append(self._project_path)
|
|
96
|
+
command.append(exec_file)
|
|
97
|
+
command.append("-formatOutput -useSubdir")
|
|
98
|
+
p = subprocess.Popen(" ".join(command))
|
|
99
|
+
p.wait()
|
|
100
|
+
|
|
101
|
+
def export_3d_cad(
|
|
102
|
+
self, format_3d="Q3D", output_folder=None, net_list=None, num_cores=None, aedt_file_name=None, hidden=False
|
|
103
|
+
): # pragma: no cover
|
|
104
|
+
"""Export edb to Q3D or HFSS
|
|
105
|
+
|
|
106
|
+
Parameters
|
|
107
|
+
----------
|
|
108
|
+
format_3d : str, default ``Q3D``
|
|
109
|
+
output_folder : str
|
|
110
|
+
Output file folder. If `` then the aedb parent folder is used
|
|
111
|
+
net_list : list, default ``None``
|
|
112
|
+
Define Nets to Export. if None, all nets will be exported
|
|
113
|
+
num_cores : int, optional
|
|
114
|
+
Define number of cores to use during export
|
|
115
|
+
aedt_file_name : str, optional
|
|
116
|
+
Output aedt file name (without .aedt extension). If `` then default naming is used
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
str
|
|
120
|
+
path to aedt file
|
|
121
|
+
"""
|
|
122
|
+
if not output_folder:
|
|
123
|
+
output_folder = os.path.dirname(self.projectpath)
|
|
124
|
+
scriptname = os.path.join(output_folder, "export_cad.py")
|
|
125
|
+
with open(scriptname, "w") as f:
|
|
126
|
+
f.write("import os\n")
|
|
127
|
+
f.write("edbpath = r'{}'\n".format(self.projectpath))
|
|
128
|
+
f.write("exportOptions = os.path.join(r'{}', 'options.config')\n".format(output_folder))
|
|
129
|
+
f.write("oDoc.ScrImportEDB(edbpath)\n")
|
|
130
|
+
f.write("oDoc.ScrSaveProjectAs(os.path.join(r'{}','{}'))\n".format(output_folder, "test.siw"))
|
|
131
|
+
if net_list:
|
|
132
|
+
f.write("allnets = []\n")
|
|
133
|
+
for el in net_list:
|
|
134
|
+
f.write("allnets.append('{}')\n".format(el))
|
|
135
|
+
f.write("for i in range(0, len(allnets)):\n")
|
|
136
|
+
f.write(" if allnets[i] != 'DUMMY':\n")
|
|
137
|
+
f.write(" oDoc.ScrSelectNet(allnets[i], 1)\n")
|
|
138
|
+
f.write("oDoc.ScrSetOptionsFor3DModelExport(exportOptions)\n")
|
|
139
|
+
if not aedt_file_name:
|
|
140
|
+
aedt_file_name = format_3d + "_siwave.aedt"
|
|
141
|
+
f.write("q3d_filename = os.path.join(r'{}', '{}')\n".format(output_folder, aedt_file_name))
|
|
142
|
+
if num_cores:
|
|
143
|
+
f.write("oDoc.ScrSetNumCpusToUse('{}')\n".format(num_cores))
|
|
144
|
+
self.nbcores = num_cores
|
|
145
|
+
f.write("oDoc.ScrExport3DModel('{}', q3d_filename)\n".format(format_3d))
|
|
146
|
+
f.write("oDoc.ScrCloseProject()\n")
|
|
147
|
+
f.write("oApp.Quit()\n")
|
|
148
|
+
if is_linux:
|
|
149
|
+
_exe = '"' + os.path.join(self.installer_path, "siwave") + '"'
|
|
150
|
+
else:
|
|
151
|
+
_exe = '"' + os.path.join(self.installer_path, "siwave.exe") + '"'
|
|
152
|
+
command = [_exe]
|
|
153
|
+
if hidden:
|
|
154
|
+
command.append("-embedding")
|
|
155
|
+
command.append("-RunScriptAndExit")
|
|
156
|
+
command.append(scriptname)
|
|
157
|
+
print(command)
|
|
158
|
+
os.system(" ".join(command))
|
|
159
|
+
# p1 = subprocess.call(" ".join(command))
|
|
160
|
+
# p1.wait()
|
|
161
|
+
return os.path.join(output_folder, aedt_file_name)
|
|
162
|
+
|
|
163
|
+
def export_dc_report(
|
|
164
|
+
self,
|
|
165
|
+
siwave_project,
|
|
166
|
+
solution_name,
|
|
167
|
+
output_folder=None,
|
|
168
|
+
html_report=True,
|
|
169
|
+
vias=True,
|
|
170
|
+
voltage_probes=True,
|
|
171
|
+
current_sources=True,
|
|
172
|
+
voltage_sources=True,
|
|
173
|
+
power_tree=True,
|
|
174
|
+
loop_res=True,
|
|
175
|
+
hidden=True,
|
|
176
|
+
):
|
|
177
|
+
"""Close EDB and solve it with Siwave.
|
|
178
|
+
|
|
179
|
+
Parameters
|
|
180
|
+
----------
|
|
181
|
+
siwave_project : str
|
|
182
|
+
Siwave full project name.
|
|
183
|
+
solution_name : str
|
|
184
|
+
Siwave DC Analysis name.
|
|
185
|
+
output_folder : str, optional
|
|
186
|
+
Ouptu folder where files will be downloaded.
|
|
187
|
+
html_report : bool, optional
|
|
188
|
+
Either if generate or not html report. Default is `True`.
|
|
189
|
+
vias : bool, optional
|
|
190
|
+
Either if generate or not vias report. Default is `True`.
|
|
191
|
+
voltage_probes : bool, optional
|
|
192
|
+
Either if generate or not voltage probe report. Default is `True`.
|
|
193
|
+
current_sources : bool, optional
|
|
194
|
+
Either if generate or not current source report. Default is `True`.
|
|
195
|
+
voltage_sources : bool, optional
|
|
196
|
+
Either if generate or not voltage source report. Default is `True`.
|
|
197
|
+
power_tree : bool, optional
|
|
198
|
+
Either if generate or not power tree image. Default is `True`.
|
|
199
|
+
loop_res : bool, optional
|
|
200
|
+
Either if generate or not loop resistance report. Default is `True`.
|
|
201
|
+
|
|
202
|
+
Returns
|
|
203
|
+
-------
|
|
204
|
+
list
|
|
205
|
+
list of files generated.
|
|
206
|
+
"""
|
|
207
|
+
if not output_folder:
|
|
208
|
+
output_folder = os.path.dirname(self.projectpath)
|
|
209
|
+
output_list = []
|
|
210
|
+
scriptname = os.path.normpath(os.path.join(os.path.normpath(output_folder), "export_results.py"))
|
|
211
|
+
with open(scriptname, "w") as f:
|
|
212
|
+
f.write("oApp.OpenProject(r'{}')\n".format(siwave_project))
|
|
213
|
+
if html_report:
|
|
214
|
+
f.write("proj = oApp.GetActiveProject()\n")
|
|
215
|
+
|
|
216
|
+
f.write("proj.ScrExportDcSimReportColorBarProperties(14,2,False,True)\n")
|
|
217
|
+
|
|
218
|
+
f.write("proj.ScrExportDcSimReportScaling('All','All',-1,-1,False)\n")
|
|
219
|
+
report_name = os.path.join(output_folder, solution_name + ".htm")
|
|
220
|
+
f.write("proj.ScrExportDcSimReport('{}','White',r'{}')\n".format(solution_name, report_name))
|
|
221
|
+
output_list.append(report_name)
|
|
222
|
+
if vias:
|
|
223
|
+
via_name = os.path.join(output_folder, "vias.txt")
|
|
224
|
+
f.write("proj.ScrExportElementData('{}',r'{}','Vias')\n".format(solution_name, via_name))
|
|
225
|
+
output_list.append(via_name)
|
|
226
|
+
|
|
227
|
+
if voltage_probes:
|
|
228
|
+
probes_names = os.path.join(output_folder, "voltage_probes.txt")
|
|
229
|
+
f.write("proj.ScrExportElementData('{}',r'{}','Voltage Probes')\n".format(solution_name, probes_names))
|
|
230
|
+
output_list.append(probes_names)
|
|
231
|
+
|
|
232
|
+
if current_sources:
|
|
233
|
+
source_name = os.path.join(output_folder, "current_sources.txt")
|
|
234
|
+
|
|
235
|
+
f.write("proj.ScrExportElementData('{}',r'{}','Current Sources')\n".format(solution_name, source_name))
|
|
236
|
+
output_list.append(source_name)
|
|
237
|
+
|
|
238
|
+
if voltage_sources:
|
|
239
|
+
sources = os.path.join(output_folder, "v_sources.txt")
|
|
240
|
+
|
|
241
|
+
f.write("proj.ScrExportElementData('{}',r'{}','Voltage Sources')\n".format(solution_name, sources))
|
|
242
|
+
output_list.append(sources)
|
|
243
|
+
|
|
244
|
+
if power_tree:
|
|
245
|
+
csv_file = os.path.join(output_folder, "powertree.csv")
|
|
246
|
+
c = open(csv_file, "w")
|
|
247
|
+
c.close()
|
|
248
|
+
png_file = os.path.join(output_folder, "powertree.png")
|
|
249
|
+
f.write("proj.ScrExportDcPowerTree('{}',r'{}', r'{}' )\n".format(solution_name, csv_file, png_file))
|
|
250
|
+
output_list.append(png_file)
|
|
251
|
+
|
|
252
|
+
if loop_res:
|
|
253
|
+
f.write("sourceNames=[]\n")
|
|
254
|
+
f.write("sourceData=[]\n")
|
|
255
|
+
f.write("proj.ScrReadDCLoopResInfo('{}', sourceNames, sourceData)\n".format(solution_name))
|
|
256
|
+
loop_res = os.path.join(output_folder, "loop_res.txt")
|
|
257
|
+
f.write("with open(r'{}','w') as f:\n".format(loop_res))
|
|
258
|
+
|
|
259
|
+
f.write(" f.writelines('Sources\tValue\\n')\n")
|
|
260
|
+
|
|
261
|
+
f.write(" for a, b in zip(sourceNames, sourceData):\n")
|
|
262
|
+
|
|
263
|
+
f.write(" f.writelines(a + '\t' + b + '\\n')\n")
|
|
264
|
+
output_list.append(loop_res)
|
|
265
|
+
|
|
266
|
+
f.write("proj.ScrCloseProject()\n")
|
|
267
|
+
|
|
268
|
+
f.write("oApp.Quit()\n")
|
|
269
|
+
if is_linux:
|
|
270
|
+
_exe = '"' + os.path.join(self.installer_path, "siwave") + '"'
|
|
271
|
+
else:
|
|
272
|
+
_exe = '"' + os.path.join(self.installer_path, "siwave.exe") + '"'
|
|
273
|
+
command = [_exe]
|
|
274
|
+
if hidden:
|
|
275
|
+
command.append("-embedding")
|
|
276
|
+
command.append("-RunScriptAndExit")
|
|
277
|
+
command.append('"' + scriptname + '"')
|
|
278
|
+
print(command)
|
|
279
|
+
if os.name == "posix":
|
|
280
|
+
p = subprocess.Popen(command)
|
|
281
|
+
|
|
282
|
+
else:
|
|
283
|
+
p = subprocess.Popen(" ".join(command))
|
|
284
|
+
p.wait()
|
|
285
|
+
return output_list
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Settings(object):
|
|
7
|
+
"""Manages all PyEDB environment variables and global settings."""
|
|
8
|
+
|
|
9
|
+
def __init__(self):
|
|
10
|
+
self.remote_rpc_session = False
|
|
11
|
+
self._enable_screen_logs = True
|
|
12
|
+
self._edb_dll_path = None
|
|
13
|
+
self._enable_logger = True
|
|
14
|
+
self._enable_file_logs = True
|
|
15
|
+
self.pyedb_server_path = ""
|
|
16
|
+
self._logger_file_path = None
|
|
17
|
+
self._logger_formatter = "%(asctime)s:%(destination)s:%(extra)s%(levelname)-8s:%(message)s"
|
|
18
|
+
self._logger_datefmt = "%Y/%m/%d %H.%M.%S"
|
|
19
|
+
self._enable_debug_edb_logger = False
|
|
20
|
+
self._enable_debug_grpc_api_logger = False
|
|
21
|
+
self._enable_debug_methods_argument_logger = False
|
|
22
|
+
self._enable_debug_geometry_operator_logger = False
|
|
23
|
+
self._enable_debug_internal_methods_logger = False
|
|
24
|
+
self._enable_debug_logger = False
|
|
25
|
+
self._enable_error_handler = True
|
|
26
|
+
self.formatter = None
|
|
27
|
+
self._project_properties = {}
|
|
28
|
+
self._project_time_stamp = 0
|
|
29
|
+
self._disable_bounding_box_sat = False
|
|
30
|
+
self._force_error_on_missing_project = False
|
|
31
|
+
self._enable_pandas_output = False
|
|
32
|
+
self.time_tick = time.time()
|
|
33
|
+
self._global_log_file_name = "pyedb_{}.log".format(os.path.split(os.path.expanduser("~"))[-1])
|
|
34
|
+
self._enable_global_log_file = True
|
|
35
|
+
self._enable_local_log_file = False
|
|
36
|
+
self._global_log_file_size = 10
|
|
37
|
+
self._lsf_queue = None
|
|
38
|
+
self._edb_environment_variables = {}
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def edb_environment_variables(self):
|
|
42
|
+
"""Environment variables that are set before launching a new AEDT session,
|
|
43
|
+
including those that enable the beta features."""
|
|
44
|
+
return self._edb_environment_variables
|
|
45
|
+
|
|
46
|
+
@edb_environment_variables.setter
|
|
47
|
+
def edb_environment_variables(self, value):
|
|
48
|
+
self._edb_environment_variables = value
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def aedt_version(self):
|
|
52
|
+
"""AEDT version in the form ``"2023.x"``. In AEDT 2022 R2 and later,
|
|
53
|
+
evaluating a bounding box by exporting a SAT file is disabled."""
|
|
54
|
+
return self._aedt_version
|
|
55
|
+
|
|
56
|
+
@aedt_version.setter
|
|
57
|
+
def aedt_version(self, value):
|
|
58
|
+
self._aedt_version = value
|
|
59
|
+
if self._aedt_version >= "2023.1":
|
|
60
|
+
self.disable_bounding_box_sat = True
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def global_log_file_size(self):
|
|
64
|
+
"""Global PyEDB log file size in MB. The default value is ``10``."""
|
|
65
|
+
return self._global_log_file_size
|
|
66
|
+
|
|
67
|
+
@global_log_file_size.setter
|
|
68
|
+
def global_log_file_size(self, value):
|
|
69
|
+
self._global_log_file_size = value
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def enable_global_log_file(self):
|
|
73
|
+
"""Flag for enabling and disabling the global PyEDB log file located in the global temp folder.
|
|
74
|
+
The default is ``True``."""
|
|
75
|
+
return self._enable_global_log_file
|
|
76
|
+
|
|
77
|
+
@enable_global_log_file.setter
|
|
78
|
+
def enable_global_log_file(self, value):
|
|
79
|
+
self._enable_global_log_file = value
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def enable_local_log_file(self):
|
|
83
|
+
"""Flag for enabling and disabling the local PyEDB log file located
|
|
84
|
+
in the ``projectname.pyedb`` project folder. The default is ``True``."""
|
|
85
|
+
return self._enable_local_log_file
|
|
86
|
+
|
|
87
|
+
@enable_local_log_file.setter
|
|
88
|
+
def enable_local_log_file(self, value):
|
|
89
|
+
self._enable_local_log_file = value
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def global_log_file_name(self):
|
|
93
|
+
"""Global PyEDB log file path. The default is ``pyedb_username.log``."""
|
|
94
|
+
return self._global_log_file_name
|
|
95
|
+
|
|
96
|
+
@global_log_file_name.setter
|
|
97
|
+
def global_log_file_name(self, value):
|
|
98
|
+
self._global_log_file_name = value
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def enable_debug_methods_argument_logger(self):
|
|
102
|
+
"""Flag for whether to write out the method's arguments in the debug logger.
|
|
103
|
+
The default is ``False``."""
|
|
104
|
+
return self._enable_debug_methods_argument_logger
|
|
105
|
+
|
|
106
|
+
@enable_debug_methods_argument_logger.setter
|
|
107
|
+
def enable_debug_methods_argument_logger(self, val):
|
|
108
|
+
self._enable_debug_methods_argument_logger = val
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def logger(self):
|
|
112
|
+
"""Active logger."""
|
|
113
|
+
try:
|
|
114
|
+
return logging.getLogger("Global")
|
|
115
|
+
except: # pragma: no cover
|
|
116
|
+
return logging.getLogger(__name__)
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def enable_error_handler(self):
|
|
120
|
+
"""Flag for enabling and disabling the internal PyEDB error handling."""
|
|
121
|
+
return self._enable_error_handler
|
|
122
|
+
|
|
123
|
+
@enable_error_handler.setter
|
|
124
|
+
def enable_error_handler(self, val):
|
|
125
|
+
self._enable_error_handler = val
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def enable_file_logs(self):
|
|
129
|
+
"""Flag for enabling and disabling the logging to a file."""
|
|
130
|
+
return self._enable_file_logs
|
|
131
|
+
|
|
132
|
+
@enable_file_logs.setter
|
|
133
|
+
def enable_file_logs(self, val):
|
|
134
|
+
self._enable_file_logs = val
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def enable_logger(self):
|
|
138
|
+
"""Flag for enabling and disabling the logging overall."""
|
|
139
|
+
return self._enable_logger
|
|
140
|
+
|
|
141
|
+
@enable_logger.setter
|
|
142
|
+
def enable_logger(self, val):
|
|
143
|
+
self._enable_logger = val
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def logger_file_path(self):
|
|
147
|
+
"""PyEDB log file path."""
|
|
148
|
+
return self._logger_file_path
|
|
149
|
+
|
|
150
|
+
@logger_file_path.setter
|
|
151
|
+
def logger_file_path(self, val):
|
|
152
|
+
self._logger_file_path = val
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def logger_formatter(self):
|
|
156
|
+
"""Message format of the log entries.
|
|
157
|
+
The default is ``'%(asctime)s:%(destination)s:%(extra)s%(levelname)-8s:%(message)s'``"""
|
|
158
|
+
return self._logger_formatter
|
|
159
|
+
|
|
160
|
+
@logger_formatter.setter
|
|
161
|
+
def logger_formatter(self, val):
|
|
162
|
+
self._logger_formatter = val
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def logger_datefmt(self):
|
|
166
|
+
"""Date format of the log entries.
|
|
167
|
+
The default is ``'%Y/%m/%d %H.%M.%S'``"""
|
|
168
|
+
return self._logger_datefmt
|
|
169
|
+
|
|
170
|
+
@logger_datefmt.setter
|
|
171
|
+
def logger_datefmt(self, val):
|
|
172
|
+
self._logger_datefmt = val
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def enable_debug_edb_logger(self):
|
|
176
|
+
"""Flag for enabling and disabling the logger for any EDB API methods."""
|
|
177
|
+
return self._enable_debug_edb_logger
|
|
178
|
+
|
|
179
|
+
@enable_debug_edb_logger.setter
|
|
180
|
+
def enable_debug_edb_logger(self, val):
|
|
181
|
+
self._enable_debug_edb_logger = val
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def enable_debug_internal_methods_logger(self):
|
|
185
|
+
"""Flag for enabling and disabling the logging for internal methods.
|
|
186
|
+
This setting is useful for debug purposes."""
|
|
187
|
+
return self._enable_debug_internal_methods_logger
|
|
188
|
+
|
|
189
|
+
@enable_debug_internal_methods_logger.setter
|
|
190
|
+
def enable_debug_internal_methods_logger(self, val):
|
|
191
|
+
self._enable_debug_internal_methods_logger = val
|
|
192
|
+
|
|
193
|
+
@property
|
|
194
|
+
def enable_debug_logger(self):
|
|
195
|
+
"""Flag for enabling and disabling the debug level logger."""
|
|
196
|
+
return self._enable_debug_logger
|
|
197
|
+
|
|
198
|
+
@enable_debug_logger.setter
|
|
199
|
+
def enable_debug_logger(self, val):
|
|
200
|
+
self._enable_debug_logger = val
|
|
201
|
+
|
|
202
|
+
# TODO: Not sure if needed, see with Simon
|
|
203
|
+
@property
|
|
204
|
+
def enable_screen_logs(self):
|
|
205
|
+
"""Flag for enabling and disabling the logging to STDOUT."""
|
|
206
|
+
return self._enable_screen_logs
|
|
207
|
+
|
|
208
|
+
@enable_screen_logs.setter
|
|
209
|
+
def enable_screen_logs(self, val):
|
|
210
|
+
self._enable_screen_logs = val
|
|
211
|
+
|
|
212
|
+
# TODO: Not sure if needed, see with Simon
|
|
213
|
+
@property
|
|
214
|
+
def edb_dll_path(self):
|
|
215
|
+
"""Optional path for the EDB DLL file."""
|
|
216
|
+
return self._edb_dll_path
|
|
217
|
+
|
|
218
|
+
@edb_dll_path.setter
|
|
219
|
+
def edb_dll_path(self, value):
|
|
220
|
+
if os.path.exists(value):
|
|
221
|
+
self._edb_dll_path = value
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
settings = Settings()
|
|
File without changes
|
|
File without changes
|
pyedb/ipc2581/bom/bom.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Bom(object):
|
|
5
|
+
def __init__(self, edb):
|
|
6
|
+
self._edb = edb
|
|
7
|
+
self.name = self._edb.cell_names[0]
|
|
8
|
+
self.revision = "1.0"
|
|
9
|
+
self.step_ref = "1.0"
|
|
10
|
+
self.bom_items = []
|
|
11
|
+
|
|
12
|
+
def write_xml(self, root): # pragma no cover
|
|
13
|
+
bom = ET.SubElement(root, "Bom")
|
|
14
|
+
bom.set("name", self.name)
|
|
15
|
+
bom_header = ET.SubElement(bom, "BomHeader")
|
|
16
|
+
bom_header.set("assembly", self.name)
|
|
17
|
+
bom_header.set("revision", self.revision)
|
|
18
|
+
step_ref = ET.SubElement(bom_header, "StepRef")
|
|
19
|
+
step_ref.set("name", self.name)
|
|
20
|
+
for bom_item in self.bom_items:
|
|
21
|
+
bom_item.write_xml(bom)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
from pyedb.ipc2581.bom.characteristics import Characteristics
|
|
3
|
+
from pyedb.ipc2581.bom.refdes import RefDes
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BomItem(object):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.part_name = ""
|
|
9
|
+
self.quantity = "1"
|
|
10
|
+
self.pin_count = "1"
|
|
11
|
+
self.category = "ELECTRICAL"
|
|
12
|
+
self.refdes_list = []
|
|
13
|
+
self.charactistics = Characteristics()
|
|
14
|
+
|
|
15
|
+
def write_xml(self, bom): # pragma no cover
|
|
16
|
+
bom_item = ET.SubElement(bom, "BomItem")
|
|
17
|
+
bom_item.set("OEMDesignNumberRef", self.part_name)
|
|
18
|
+
bom_item.set("quantity", str(self.quantity))
|
|
19
|
+
bom_item.set("pinCount", str(self.pin_count))
|
|
20
|
+
bom_item.set("category", self.category)
|
|
21
|
+
bom_item.set("category", self.category)
|
|
22
|
+
for refdes in self.refdes_list:
|
|
23
|
+
refdes.write_xml(bom_item)
|
|
24
|
+
self.charactistics.write_xml(bom_item)
|
|
25
|
+
|
|
26
|
+
def add_refdes(self, component_name=None, package_def=None, populate=True, placement_layer=""): # pragma no cover
|
|
27
|
+
refdes = RefDes()
|
|
28
|
+
refdes.name = component_name
|
|
29
|
+
refdes.populate = str(populate)
|
|
30
|
+
refdes.packaged_def = package_def
|
|
31
|
+
refdes.placement_layer = placement_layer
|
|
32
|
+
self.refdes_list.append(refdes)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Characteristics(object):
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self.category = "ELECTRICAL"
|
|
7
|
+
self.device_type = ""
|
|
8
|
+
self.component_class = ""
|
|
9
|
+
self.value = ""
|
|
10
|
+
|
|
11
|
+
def write_xml(self, bom_item): # pragma no cover
|
|
12
|
+
characteristic = ET.SubElement(bom_item, "Characteristics")
|
|
13
|
+
characteristic.set("category", self.category)
|
|
14
|
+
component_type = ET.SubElement(characteristic, "Textual")
|
|
15
|
+
component_type.set("definitionSource", "ANSYS")
|
|
16
|
+
component_type.set("textualCharacteristicName", "DEVICE_TYPE")
|
|
17
|
+
component_type.set("textualCharacteristicValue", "{}_{}".format(self.device_type, self.value))
|
|
18
|
+
component_class = ET.SubElement(characteristic, "Textual")
|
|
19
|
+
component_class.set("definitionSource", "ANSYS")
|
|
20
|
+
component_class.set("textualCharacteristicName", "COMP_CLASS")
|
|
21
|
+
component_class.set("textualCharacteristicValue", "{}".format(self.component_class))
|
|
22
|
+
component_value = ET.SubElement(characteristic, "Textual")
|
|
23
|
+
component_value.set("definitionSource", "ANSYS")
|
|
24
|
+
component_value.set("textualCharacteristicName", "VALUE")
|
|
25
|
+
component_value.set("textualCharacteristicValue", "{}".format(self.value))
|
|
26
|
+
component_parent_type = ET.SubElement(characteristic, "Textual")
|
|
27
|
+
component_parent_type.set("definitionSource", "ANSYS")
|
|
28
|
+
component_parent_type.set("textualCharacteristicName", "PARENT_PPT_PART")
|
|
29
|
+
component_parent_type.set("textualCharacteristicValue", "{}_{}".format(self.device_type, self.value))
|
|
30
|
+
component_parent = ET.SubElement(characteristic, "Textual")
|
|
31
|
+
component_parent.set("definitionSource", "ANSYS")
|
|
32
|
+
component_parent.set("textualCharacteristicName", "PARENT_PPT")
|
|
33
|
+
component_parent.set("textualCharacteristicValue", "{}".format(self.device_type))
|
|
34
|
+
component_parent2 = ET.SubElement(characteristic, "Textual")
|
|
35
|
+
component_parent2.set("definitionSource", "ANSYS")
|
|
36
|
+
component_parent2.set("textualCharacteristicName", "PARENT_PART_TYPE")
|
|
37
|
+
component_parent2.set("textualCharacteristicValue", "{}".format(self.device_type))
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class RefDes(object):
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self.name = ""
|
|
7
|
+
self.packaged_def = ""
|
|
8
|
+
self.populate = "True"
|
|
9
|
+
self.placement_layer = ""
|
|
10
|
+
|
|
11
|
+
def write_xml(self, bom_item): # pragma no cover
|
|
12
|
+
refdes = ET.SubElement(bom_item, "RefDes")
|
|
13
|
+
refdes.set("name", self.name)
|
|
14
|
+
refdes.set("packageRef", self.packaged_def)
|
|
15
|
+
refdes.set("populate", self.populate)
|
|
16
|
+
refdes.set("layerRef", self.placement_layer)
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Color(object):
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self._r = 0
|
|
7
|
+
self._g = 0
|
|
8
|
+
self._b = 0
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def r(self):
|
|
12
|
+
return self._r
|
|
13
|
+
|
|
14
|
+
@r.setter
|
|
15
|
+
def r(self, value):
|
|
16
|
+
self._r = value
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def g(self):
|
|
20
|
+
return self._g
|
|
21
|
+
|
|
22
|
+
@g.setter
|
|
23
|
+
def g(self, value):
|
|
24
|
+
self._g = value
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def b(self):
|
|
28
|
+
return self._b
|
|
29
|
+
|
|
30
|
+
@b.setter
|
|
31
|
+
def b(self, value):
|
|
32
|
+
self._b = value
|
|
33
|
+
|
|
34
|
+
def write_xml(self, entry_color=None): # pragma no cover
|
|
35
|
+
color = ET.SubElement(entry_color, "Color")
|
|
36
|
+
color.set("r", str(self.r))
|
|
37
|
+
color.set("g", str(self.g))
|
|
38
|
+
color.set("b", str(self.b))
|