pyedb 0.31.0__py3-none-any.whl → 0.34.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyedb might be problematic. Click here for more details.
- pyedb/__init__.py +1 -27
- pyedb/common/__init__.py +0 -0
- pyedb/common/nets.py +488 -0
- pyedb/configuration/cfg_common.py +20 -0
- pyedb/configuration/cfg_components.py +218 -57
- pyedb/configuration/cfg_data.py +6 -0
- pyedb/configuration/cfg_modeler.py +139 -0
- pyedb/configuration/cfg_operations.py +5 -4
- pyedb/configuration/cfg_padstacks.py +319 -55
- pyedb/configuration/cfg_ports_sources.py +99 -7
- pyedb/configuration/cfg_s_parameter_models.py +6 -6
- pyedb/configuration/configuration.py +31 -9
- pyedb/dotnet/clr_module.py +92 -32
- pyedb/dotnet/edb.py +54 -5
- pyedb/dotnet/edb_core/cell/hierarchy/component.py +0 -202
- pyedb/dotnet/edb_core/cell/layout.py +1 -1
- pyedb/dotnet/edb_core/cell/primitive/primitive.py +5 -27
- pyedb/dotnet/edb_core/edb_data/control_file.py +21 -0
- pyedb/dotnet/edb_core/edb_data/layer_data.py +60 -6
- pyedb/dotnet/edb_core/edb_data/nets_data.py +6 -1
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +16 -222
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +31 -0
- pyedb/dotnet/edb_core/hfss.py +2 -2
- pyedb/dotnet/edb_core/layout_validation.py +1 -3
- pyedb/dotnet/edb_core/materials.py +38 -38
- pyedb/dotnet/edb_core/modeler.py +4 -1
- pyedb/dotnet/edb_core/nets.py +2 -373
- pyedb/generic/filesystem.py +2 -5
- {pyedb-0.31.0.dist-info → pyedb-0.34.1.dist-info}/METADATA +12 -9
- {pyedb-0.31.0.dist-info → pyedb-0.34.1.dist-info}/RECORD +32 -29
- {pyedb-0.31.0.dist-info → pyedb-0.34.1.dist-info}/WHEEL +1 -1
- {pyedb-0.31.0.dist-info → pyedb-0.34.1.dist-info}/LICENSE +0 -0
|
@@ -69,6 +69,7 @@ DC_ATTRIBUTES = [
|
|
|
69
69
|
"dc_conductivity",
|
|
70
70
|
"dc_permittivity",
|
|
71
71
|
]
|
|
72
|
+
PERMEABILITY_DEFAULT_VALUE = 1
|
|
72
73
|
|
|
73
74
|
|
|
74
75
|
def get_line_float_value(line):
|
|
@@ -114,7 +115,6 @@ class Material(object):
|
|
|
114
115
|
self.__name: str = material_def.GetName()
|
|
115
116
|
self.__material_def = material_def
|
|
116
117
|
self.__dc_model = material_def.GetDielectricMaterialModel()
|
|
117
|
-
self.__properties: MaterialProperties = MaterialProperties()
|
|
118
118
|
|
|
119
119
|
@property
|
|
120
120
|
def name(self):
|
|
@@ -130,8 +130,7 @@ class Material(object):
|
|
|
130
130
|
def conductivity(self):
|
|
131
131
|
"""Get material conductivity."""
|
|
132
132
|
material_property_id = self.__edb_definition.MaterialPropertyId.Conductivity
|
|
133
|
-
|
|
134
|
-
return self.__properties.conductivity
|
|
133
|
+
return self.__property_value(material_property_id)
|
|
135
134
|
|
|
136
135
|
@conductivity.setter
|
|
137
136
|
def conductivity(self, value):
|
|
@@ -144,8 +143,7 @@ class Material(object):
|
|
|
144
143
|
def permittivity(self):
|
|
145
144
|
"""Get material permittivity."""
|
|
146
145
|
material_property_id = self.__edb_definition.MaterialPropertyId.Permittivity
|
|
147
|
-
|
|
148
|
-
return self.__properties.permittivity
|
|
146
|
+
return self.__property_value(material_property_id)
|
|
149
147
|
|
|
150
148
|
@permittivity.setter
|
|
151
149
|
def permittivity(self, value):
|
|
@@ -158,8 +156,7 @@ class Material(object):
|
|
|
158
156
|
def permeability(self):
|
|
159
157
|
"""Get material permeability."""
|
|
160
158
|
material_property_id = self.__edb_definition.MaterialPropertyId.Permeability
|
|
161
|
-
|
|
162
|
-
return self.__properties.permeability
|
|
159
|
+
return self.__property_value(material_property_id)
|
|
163
160
|
|
|
164
161
|
@permeability.setter
|
|
165
162
|
def permeability(self, value):
|
|
@@ -182,8 +179,7 @@ class Material(object):
|
|
|
182
179
|
def dielectric_loss_tangent(self):
|
|
183
180
|
"""Get material loss tangent."""
|
|
184
181
|
material_property_id = self.__edb_definition.MaterialPropertyId.DielectricLossTangent
|
|
185
|
-
|
|
186
|
-
return self.__properties.dielectric_loss_tangent
|
|
182
|
+
return self.__property_value(material_property_id)
|
|
187
183
|
|
|
188
184
|
@loss_tangent.setter
|
|
189
185
|
def loss_tangent(self, value):
|
|
@@ -205,9 +201,10 @@ class Material(object):
|
|
|
205
201
|
@property
|
|
206
202
|
def dc_conductivity(self):
|
|
207
203
|
"""Get material dielectric conductivity."""
|
|
204
|
+
res = None
|
|
208
205
|
if self.__dc_model:
|
|
209
|
-
|
|
210
|
-
return
|
|
206
|
+
res = self.__dc_model.GetDCConductivity()
|
|
207
|
+
return res
|
|
211
208
|
|
|
212
209
|
@dc_conductivity.setter
|
|
213
210
|
def dc_conductivity(self, value: Union[int, float]):
|
|
@@ -220,9 +217,10 @@ class Material(object):
|
|
|
220
217
|
@property
|
|
221
218
|
def dc_permittivity(self):
|
|
222
219
|
"""Get material dielectric relative permittivity"""
|
|
220
|
+
res = None
|
|
223
221
|
if self.__dc_model:
|
|
224
|
-
|
|
225
|
-
return
|
|
222
|
+
res = self.__dc_model.GetDCRelativePermitivity()
|
|
223
|
+
return res
|
|
226
224
|
|
|
227
225
|
@dc_permittivity.setter
|
|
228
226
|
def dc_permittivity(self, value: Union[int, float]):
|
|
@@ -237,9 +235,10 @@ class Material(object):
|
|
|
237
235
|
@property
|
|
238
236
|
def dielectric_model_frequency(self):
|
|
239
237
|
"""Get material frequency in GHz."""
|
|
238
|
+
res = None
|
|
240
239
|
if self.__dc_model:
|
|
241
|
-
|
|
242
|
-
return
|
|
240
|
+
res = self.__dc_model.GetFrequency()
|
|
241
|
+
return res
|
|
243
242
|
|
|
244
243
|
@dielectric_model_frequency.setter
|
|
245
244
|
def dielectric_model_frequency(self, value: Union[int, float]):
|
|
@@ -252,9 +251,10 @@ class Material(object):
|
|
|
252
251
|
@property
|
|
253
252
|
def loss_tangent_at_frequency(self):
|
|
254
253
|
"""Get material loss tangeat at frequency."""
|
|
254
|
+
res = None
|
|
255
255
|
if self.__dc_model:
|
|
256
|
-
|
|
257
|
-
return
|
|
256
|
+
res = self.__dc_model.GetLossTangentAtFrequency()
|
|
257
|
+
return res
|
|
258
258
|
|
|
259
259
|
@loss_tangent_at_frequency.setter
|
|
260
260
|
def loss_tangent_at_frequency(self, value):
|
|
@@ -268,9 +268,10 @@ class Material(object):
|
|
|
268
268
|
@property
|
|
269
269
|
def permittivity_at_frequency(self):
|
|
270
270
|
"""Get material relative permittivity at frequency."""
|
|
271
|
+
res = None
|
|
271
272
|
if self.__dc_model:
|
|
272
|
-
|
|
273
|
-
return
|
|
273
|
+
res = self.__dc_model.GetRelativePermitivityAtFrequency()
|
|
274
|
+
return res
|
|
274
275
|
|
|
275
276
|
@permittivity_at_frequency.setter
|
|
276
277
|
def permittivity_at_frequency(self, value: Union[int, float]):
|
|
@@ -284,8 +285,7 @@ class Material(object):
|
|
|
284
285
|
def magnetic_loss_tangent(self):
|
|
285
286
|
"""Get material magnetic loss tangent."""
|
|
286
287
|
material_property_id = self.__edb_definition.MaterialPropertyId.MagneticLossTangent
|
|
287
|
-
|
|
288
|
-
return self.__properties.magnetic_loss_tangent
|
|
288
|
+
return self.__property_value(material_property_id)
|
|
289
289
|
|
|
290
290
|
@magnetic_loss_tangent.setter
|
|
291
291
|
def magnetic_loss_tangent(self, value):
|
|
@@ -298,8 +298,7 @@ class Material(object):
|
|
|
298
298
|
def thermal_conductivity(self):
|
|
299
299
|
"""Get material thermal conductivity."""
|
|
300
300
|
material_property_id = self.__edb_definition.MaterialPropertyId.ThermalConductivity
|
|
301
|
-
|
|
302
|
-
return self.__properties.thermal_conductivity
|
|
301
|
+
return self.__property_value(material_property_id)
|
|
303
302
|
|
|
304
303
|
@thermal_conductivity.setter
|
|
305
304
|
def thermal_conductivity(self, value):
|
|
@@ -312,8 +311,7 @@ class Material(object):
|
|
|
312
311
|
def mass_density(self):
|
|
313
312
|
"""Get material mass density."""
|
|
314
313
|
material_property_id = self.__edb_definition.MaterialPropertyId.MassDensity
|
|
315
|
-
|
|
316
|
-
return self.__properties.mass_density
|
|
314
|
+
return self.__property_value(material_property_id)
|
|
317
315
|
|
|
318
316
|
@mass_density.setter
|
|
319
317
|
def mass_density(self, value):
|
|
@@ -326,8 +324,7 @@ class Material(object):
|
|
|
326
324
|
def youngs_modulus(self):
|
|
327
325
|
"""Get material youngs modulus."""
|
|
328
326
|
material_property_id = self.__edb_definition.MaterialPropertyId.YoungsModulus
|
|
329
|
-
|
|
330
|
-
return self.__properties.youngs_modulus
|
|
327
|
+
return self.__property_value(material_property_id)
|
|
331
328
|
|
|
332
329
|
@youngs_modulus.setter
|
|
333
330
|
def youngs_modulus(self, value):
|
|
@@ -340,8 +337,7 @@ class Material(object):
|
|
|
340
337
|
def specific_heat(self):
|
|
341
338
|
"""Get material specific heat."""
|
|
342
339
|
material_property_id = self.__edb_definition.MaterialPropertyId.SpecificHeat
|
|
343
|
-
|
|
344
|
-
return self.__properties.specific_heat
|
|
340
|
+
return self.__property_value(material_property_id)
|
|
345
341
|
|
|
346
342
|
@specific_heat.setter
|
|
347
343
|
def specific_heat(self, value):
|
|
@@ -354,8 +350,7 @@ class Material(object):
|
|
|
354
350
|
def poisson_ratio(self):
|
|
355
351
|
"""Get material poisson ratio."""
|
|
356
352
|
material_property_id = self.__edb_definition.MaterialPropertyId.PoissonsRatio
|
|
357
|
-
|
|
358
|
-
return self.__properties.poisson_ratio
|
|
353
|
+
return self.__property_value(material_property_id)
|
|
359
354
|
|
|
360
355
|
@poisson_ratio.setter
|
|
361
356
|
def poisson_ratio(self, value):
|
|
@@ -368,8 +363,7 @@ class Material(object):
|
|
|
368
363
|
def thermal_expansion_coefficient(self):
|
|
369
364
|
"""Get material thermal coefficient."""
|
|
370
365
|
material_property_id = self.__edb_definition.MaterialPropertyId.ThermalExpansionCoefficient
|
|
371
|
-
|
|
372
|
-
return self.__properties.thermal_expansion_coefficient
|
|
366
|
+
return self.__property_value(material_property_id)
|
|
373
367
|
|
|
374
368
|
@thermal_expansion_coefficient.setter
|
|
375
369
|
def thermal_expansion_coefficient(self, value):
|
|
@@ -380,10 +374,10 @@ class Material(object):
|
|
|
380
374
|
|
|
381
375
|
def to_dict(self):
|
|
382
376
|
"""Convert material into dictionary."""
|
|
383
|
-
self.__load_all_properties()
|
|
377
|
+
properties = self.__load_all_properties()
|
|
384
378
|
|
|
385
379
|
res = {"name": self.name}
|
|
386
|
-
res.update(
|
|
380
|
+
res.update(properties.model_dump())
|
|
387
381
|
return res
|
|
388
382
|
|
|
389
383
|
def update(self, input_dict: dict):
|
|
@@ -419,10 +413,13 @@ class Material(object):
|
|
|
419
413
|
"""
|
|
420
414
|
return self.__edb.edb_value(value)
|
|
421
415
|
|
|
422
|
-
def __load_all_properties(self):
|
|
416
|
+
def __load_all_properties(self) -> MaterialProperties:
|
|
423
417
|
"""Load all properties of the material."""
|
|
424
|
-
|
|
425
|
-
|
|
418
|
+
res = MaterialProperties()
|
|
419
|
+
for property in res.model_dump().keys():
|
|
420
|
+
value = getattr(self, property)
|
|
421
|
+
setattr(res, property, value)
|
|
422
|
+
return res
|
|
426
423
|
|
|
427
424
|
def __property_value(self, material_property_id):
|
|
428
425
|
"""Get property value from a material property id."""
|
|
@@ -507,6 +504,9 @@ class Materials(object):
|
|
|
507
504
|
|
|
508
505
|
material_def = self.__edb_definition.MaterialDef.Create(self.__edb.active_db, name)
|
|
509
506
|
material = Material(self.__edb, material_def)
|
|
507
|
+
# Apply default values to the material
|
|
508
|
+
if "permeability" not in kwargs:
|
|
509
|
+
kwargs["permeability"] = PERMEABILITY_DEFAULT_VALUE
|
|
510
510
|
attributes_input_dict = {key: val for (key, val) in kwargs.items() if key in ATTRIBUTES + DC_ATTRIBUTES}
|
|
511
511
|
if "loss_tangent" in kwargs: # pragma: no cover
|
|
512
512
|
warnings.warn(
|
pyedb/dotnet/edb_core/modeler.py
CHANGED
|
@@ -188,7 +188,10 @@ class Modeler(object):
|
|
|
188
188
|
for lay in self._pedb.stackup.non_stackup_layers:
|
|
189
189
|
_primitives_by_layer[lay] = []
|
|
190
190
|
for i in self._layout.primitives:
|
|
191
|
-
|
|
191
|
+
layer = i.layer
|
|
192
|
+
if not layer:
|
|
193
|
+
continue
|
|
194
|
+
lay = layer.name
|
|
192
195
|
if lay in _primitives_by_layer:
|
|
193
196
|
_primitives_by_layer[lay].append(i)
|
|
194
197
|
return _primitives_by_layer
|
pyedb/dotnet/edb_core/nets.py
CHANGED
|
@@ -22,18 +22,15 @@
|
|
|
22
22
|
|
|
23
23
|
from __future__ import absolute_import # noreorder
|
|
24
24
|
|
|
25
|
-
import os
|
|
26
|
-
import time
|
|
27
25
|
import warnings
|
|
28
26
|
|
|
27
|
+
from pyedb.common.nets import CommonNets
|
|
29
28
|
from pyedb.dotnet.edb_core.edb_data.nets_data import EDBNetsData
|
|
30
|
-
from pyedb.generic.constants import CSS4_COLORS
|
|
31
29
|
from pyedb.generic.general_methods import generate_unique_name
|
|
32
30
|
from pyedb.misc.utilities import compute_arc_points
|
|
33
|
-
from pyedb.modeler.geometry_operators import GeometryOperators
|
|
34
31
|
|
|
35
32
|
|
|
36
|
-
class EdbNets(
|
|
33
|
+
class EdbNets(CommonNets):
|
|
37
34
|
"""Manages EDB methods for nets management accessible from `Edb.nets` property.
|
|
38
35
|
|
|
39
36
|
Examples
|
|
@@ -381,295 +378,6 @@ class EdbNets(object):
|
|
|
381
378
|
# fmt: on
|
|
382
379
|
return x, y
|
|
383
380
|
|
|
384
|
-
def get_plot_data(
|
|
385
|
-
self,
|
|
386
|
-
nets=None,
|
|
387
|
-
layers=None,
|
|
388
|
-
color_by_net=False,
|
|
389
|
-
outline=None,
|
|
390
|
-
plot_components_on_top=False,
|
|
391
|
-
plot_components_on_bottom=False,
|
|
392
|
-
):
|
|
393
|
-
"""Return List of points for Matplotlib 2D Chart.
|
|
394
|
-
|
|
395
|
-
Parameters
|
|
396
|
-
----------
|
|
397
|
-
nets : str, list, optional
|
|
398
|
-
Name of the net or list of nets to plot. If `None` (default value) all nets will be plotted.
|
|
399
|
-
layers : str, list, optional
|
|
400
|
-
Name of the layers to include in the plot. If `None` all the signal layers will be considered.
|
|
401
|
-
color_by_net : bool, optional
|
|
402
|
-
If ``True`` the plot will be colored by net.
|
|
403
|
-
If ``False`` the plot will be colored by layer. (default)
|
|
404
|
-
outline : list, optional
|
|
405
|
-
List of points of the outline to plot.
|
|
406
|
-
plot_components_on_top : bool, optional
|
|
407
|
-
If ``True`` the components placed on top layer are plotted.
|
|
408
|
-
If ``False`` the components are not plotted. (default)
|
|
409
|
-
If nets and/or layers is specified, only the components belonging to the specified nets/layers are plotted.
|
|
410
|
-
plot_components_on_bottom : bool, optional
|
|
411
|
-
If ``True`` the components placed on bottom layer are plotted.
|
|
412
|
-
If ``False`` the components are not plotted. (default)
|
|
413
|
-
If nets and/or layers is specified, only the components belonging to the specified nets/layers are plotted.
|
|
414
|
-
|
|
415
|
-
Returns
|
|
416
|
-
-------
|
|
417
|
-
List, str: list of data to be used in plot.
|
|
418
|
-
In case of remote session it will be returned a string that could be converted \
|
|
419
|
-
to list using ast.literal_eval().
|
|
420
|
-
"""
|
|
421
|
-
start_time = time.time()
|
|
422
|
-
if not nets:
|
|
423
|
-
nets = list(self.nets.keys())
|
|
424
|
-
if isinstance(nets, str):
|
|
425
|
-
nets = [nets]
|
|
426
|
-
if not layers:
|
|
427
|
-
layers = list(self._pedb.stackup.signal_layers.keys())
|
|
428
|
-
if isinstance(layers, str):
|
|
429
|
-
layers = [layers]
|
|
430
|
-
color_index = 0
|
|
431
|
-
objects_lists = []
|
|
432
|
-
label_colors = {}
|
|
433
|
-
n_label = 0
|
|
434
|
-
max_labels = 10
|
|
435
|
-
|
|
436
|
-
if outline:
|
|
437
|
-
xt = [i[0] for i in outline]
|
|
438
|
-
yt = [i[1] for i in outline]
|
|
439
|
-
xc, yc = GeometryOperators.orient_polygon(xt, yt, clockwise=True)
|
|
440
|
-
vertices = [(i, j) for i, j in zip(xc, yc)]
|
|
441
|
-
codes = [2 for _ in vertices]
|
|
442
|
-
codes[0] = 1
|
|
443
|
-
vertices.append((0, 0))
|
|
444
|
-
codes.append(79)
|
|
445
|
-
objects_lists.append([vertices, codes, "b", "Outline", 1.0, 1.5, "contour"])
|
|
446
|
-
n_label += 1
|
|
447
|
-
layer_colors = {i: k.color for i, k in self._pedb.stackup.layers.items()}
|
|
448
|
-
top_layer = list(self._pedb.stackup.signal_layers.keys())[0]
|
|
449
|
-
bottom_layer = list(self._pedb.stackup.signal_layers.keys())[-1]
|
|
450
|
-
if plot_components_on_top or plot_components_on_bottom:
|
|
451
|
-
nc = 0
|
|
452
|
-
for comp in self._pedb.components.instances.values():
|
|
453
|
-
if not comp.is_enabled:
|
|
454
|
-
continue
|
|
455
|
-
net_names = comp.nets
|
|
456
|
-
if nets and not any([i in nets for i in net_names]):
|
|
457
|
-
continue
|
|
458
|
-
layer_name = comp.placement_layer
|
|
459
|
-
if layer_name not in layers:
|
|
460
|
-
continue
|
|
461
|
-
if plot_components_on_top and layer_name == top_layer:
|
|
462
|
-
component_color = (184 / 255, 115 / 255, 51 / 255) # this is the color used in AEDT
|
|
463
|
-
label = "Component on top layer"
|
|
464
|
-
elif plot_components_on_bottom and layer_name == bottom_layer:
|
|
465
|
-
component_color = (41 / 255, 171 / 255, 135 / 255) # 41, 171, 135
|
|
466
|
-
label = "Component on bottom layer"
|
|
467
|
-
else:
|
|
468
|
-
continue
|
|
469
|
-
cbb = comp.bounding_box
|
|
470
|
-
x = [cbb[0], cbb[0], cbb[2], cbb[2]]
|
|
471
|
-
y = [cbb[1], cbb[3], cbb[3], cbb[1]]
|
|
472
|
-
vertices = [(i, j) for i, j in zip(x, y)]
|
|
473
|
-
codes = [2 for _ in vertices]
|
|
474
|
-
codes[0] = 1
|
|
475
|
-
vertices.append((0, 0))
|
|
476
|
-
codes.append(79)
|
|
477
|
-
if label not in label_colors:
|
|
478
|
-
label_colors[label] = component_color
|
|
479
|
-
objects_lists.append([vertices, codes, label_colors[label], label, 1.0, 2.0, "contour"])
|
|
480
|
-
n_label += 1
|
|
481
|
-
else:
|
|
482
|
-
objects_lists.append([vertices, codes, label_colors[label], None, 1.0, 2.0, "contour"])
|
|
483
|
-
nc += 1
|
|
484
|
-
self._logger.debug("Plotted {} component(s)".format(nc))
|
|
485
|
-
for prim in self._pedb.modeler.primitives:
|
|
486
|
-
if prim.is_void:
|
|
487
|
-
continue
|
|
488
|
-
net_name = prim.net_name
|
|
489
|
-
layer_name = prim.layer_name
|
|
490
|
-
if nets and (net_name not in nets or layer_name not in layers):
|
|
491
|
-
continue
|
|
492
|
-
prim_type = prim.primitive_type
|
|
493
|
-
if prim_type == "path":
|
|
494
|
-
try:
|
|
495
|
-
x, y = prim.points()
|
|
496
|
-
except ValueError:
|
|
497
|
-
x = None
|
|
498
|
-
if not x:
|
|
499
|
-
continue
|
|
500
|
-
create_label = False
|
|
501
|
-
if not color_by_net:
|
|
502
|
-
label = "Layer " + layer_name
|
|
503
|
-
if label not in label_colors:
|
|
504
|
-
try:
|
|
505
|
-
color = layer_colors[layer_name]
|
|
506
|
-
c = (
|
|
507
|
-
float(color[0] / 255),
|
|
508
|
-
float(color[1] / 255),
|
|
509
|
-
float(color[2] / 255),
|
|
510
|
-
)
|
|
511
|
-
except:
|
|
512
|
-
c = list(CSS4_COLORS.keys())[color_index]
|
|
513
|
-
color_index += 1
|
|
514
|
-
if color_index >= len(CSS4_COLORS):
|
|
515
|
-
color_index = 0
|
|
516
|
-
label_colors[label] = c
|
|
517
|
-
create_label = True
|
|
518
|
-
else:
|
|
519
|
-
label = "Net " + net_name
|
|
520
|
-
if label not in label_colors:
|
|
521
|
-
label_colors[label] = list(CSS4_COLORS.keys())[color_index]
|
|
522
|
-
color_index += 1
|
|
523
|
-
if color_index >= len(CSS4_COLORS):
|
|
524
|
-
color_index = 0
|
|
525
|
-
create_label = True
|
|
526
|
-
|
|
527
|
-
if create_label and n_label <= max_labels:
|
|
528
|
-
objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
|
|
529
|
-
n_label += 1
|
|
530
|
-
else:
|
|
531
|
-
objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
|
|
532
|
-
elif prim_type == "polygon":
|
|
533
|
-
xt, yt = prim.points()
|
|
534
|
-
if not xt:
|
|
535
|
-
continue
|
|
536
|
-
x, y = GeometryOperators.orient_polygon(xt, yt, clockwise=True)
|
|
537
|
-
vertices = [(i, j) for i, j in zip(x, y)]
|
|
538
|
-
codes = [2 for _ in vertices]
|
|
539
|
-
codes[0] = 1
|
|
540
|
-
vertices.append((0, 0))
|
|
541
|
-
codes.append(79)
|
|
542
|
-
|
|
543
|
-
for void in prim.voids:
|
|
544
|
-
xvt, yvt = void.points()
|
|
545
|
-
if xvt:
|
|
546
|
-
xv, yv = GeometryOperators.orient_polygon(xvt, yvt, clockwise=False)
|
|
547
|
-
tmpV = [(i, j) for i, j in zip(xv, yv)]
|
|
548
|
-
vertices.extend(tmpV)
|
|
549
|
-
tmpC = [2 for _ in tmpV]
|
|
550
|
-
tmpC[0] = 1
|
|
551
|
-
codes.extend(tmpC)
|
|
552
|
-
vertices.append((0, 0))
|
|
553
|
-
codes.append(79)
|
|
554
|
-
|
|
555
|
-
create_label = False
|
|
556
|
-
if not color_by_net:
|
|
557
|
-
label = "Layer " + layer_name
|
|
558
|
-
if label not in label_colors:
|
|
559
|
-
try:
|
|
560
|
-
color = layer_colors[layer_name]
|
|
561
|
-
c = (
|
|
562
|
-
float(color[0] / 255),
|
|
563
|
-
float(color[1] / 255),
|
|
564
|
-
float(color[2] / 255),
|
|
565
|
-
)
|
|
566
|
-
except:
|
|
567
|
-
c = list(CSS4_COLORS.keys())[color_index]
|
|
568
|
-
color_index += 1
|
|
569
|
-
if color_index >= len(CSS4_COLORS):
|
|
570
|
-
color_index = 0
|
|
571
|
-
label_colors[label] = c
|
|
572
|
-
create_label = True
|
|
573
|
-
else:
|
|
574
|
-
label = "Net " + net_name
|
|
575
|
-
if label not in label_colors:
|
|
576
|
-
label_colors[label] = list(CSS4_COLORS.keys())[color_index]
|
|
577
|
-
color_index += 1
|
|
578
|
-
if color_index >= len(CSS4_COLORS):
|
|
579
|
-
color_index = 0
|
|
580
|
-
create_label = True
|
|
581
|
-
|
|
582
|
-
if create_label and n_label <= max_labels:
|
|
583
|
-
if layer_name == "Outline":
|
|
584
|
-
objects_lists.append([vertices, codes, label_colors[label], label, 1.0, 2.0, "contour"])
|
|
585
|
-
else:
|
|
586
|
-
objects_lists.append([vertices, codes, label_colors[label], label, 0.4, "path"])
|
|
587
|
-
n_label += 1
|
|
588
|
-
else:
|
|
589
|
-
if layer_name == "Outline":
|
|
590
|
-
objects_lists.append([vertices, codes, label_colors[label], None, 1.0, 2.0, "contour"])
|
|
591
|
-
else:
|
|
592
|
-
objects_lists.append([vertices, codes, label_colors[label], None, 0.4, "path"])
|
|
593
|
-
elif prim_type == "circle":
|
|
594
|
-
x, y = prim.points()
|
|
595
|
-
if not x:
|
|
596
|
-
continue
|
|
597
|
-
create_label = False
|
|
598
|
-
if not color_by_net:
|
|
599
|
-
label = "Layer " + layer_name
|
|
600
|
-
if label not in label_colors:
|
|
601
|
-
try:
|
|
602
|
-
color = layer_colors[layer_name]
|
|
603
|
-
c = (
|
|
604
|
-
float(color[0] / 255),
|
|
605
|
-
float(color[1] / 255),
|
|
606
|
-
float(color[2] / 255),
|
|
607
|
-
)
|
|
608
|
-
except:
|
|
609
|
-
c = list(CSS4_COLORS.keys())[color_index]
|
|
610
|
-
color_index += 1
|
|
611
|
-
if color_index >= len(CSS4_COLORS):
|
|
612
|
-
color_index = 0
|
|
613
|
-
label_colors[label] = c
|
|
614
|
-
create_label = True
|
|
615
|
-
else:
|
|
616
|
-
label = "Net " + net_name
|
|
617
|
-
if label not in label_colors:
|
|
618
|
-
label_colors[label] = list(CSS4_COLORS.keys())[color_index]
|
|
619
|
-
color_index += 1
|
|
620
|
-
if color_index >= len(CSS4_COLORS):
|
|
621
|
-
color_index = 0
|
|
622
|
-
create_label = True
|
|
623
|
-
|
|
624
|
-
if create_label and n_label <= max_labels:
|
|
625
|
-
objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
|
|
626
|
-
n_label += 1
|
|
627
|
-
else:
|
|
628
|
-
objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
|
|
629
|
-
elif prim_type == "rectangle":
|
|
630
|
-
x, y = prim.points()
|
|
631
|
-
if not x:
|
|
632
|
-
continue
|
|
633
|
-
create_label = False
|
|
634
|
-
if not color_by_net:
|
|
635
|
-
label = "Layer " + layer_name
|
|
636
|
-
if label not in label_colors:
|
|
637
|
-
try:
|
|
638
|
-
color = layer_colors[layer_name]
|
|
639
|
-
c = (
|
|
640
|
-
float(color[0] / 255),
|
|
641
|
-
float(color[1] / 255),
|
|
642
|
-
float(color[2] / 255),
|
|
643
|
-
)
|
|
644
|
-
except:
|
|
645
|
-
c = list(CSS4_COLORS.keys())[color_index]
|
|
646
|
-
color_index += 1
|
|
647
|
-
if color_index >= len(CSS4_COLORS):
|
|
648
|
-
color_index = 0
|
|
649
|
-
label_colors[label] = c
|
|
650
|
-
create_label = True
|
|
651
|
-
else:
|
|
652
|
-
label = "Net " + net_name
|
|
653
|
-
if label not in label_colors:
|
|
654
|
-
label_colors[label] = list(CSS4_COLORS.keys())[color_index]
|
|
655
|
-
color_index += 1
|
|
656
|
-
if color_index >= len(CSS4_COLORS):
|
|
657
|
-
color_index = 0
|
|
658
|
-
create_label = True
|
|
659
|
-
|
|
660
|
-
if create_label and n_label <= max_labels:
|
|
661
|
-
objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
|
|
662
|
-
n_label += 1
|
|
663
|
-
else:
|
|
664
|
-
objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
|
|
665
|
-
|
|
666
|
-
end_time = time.time() - start_time
|
|
667
|
-
self._logger.info("Nets Point Generation time %s seconds", round(end_time, 3))
|
|
668
|
-
if os.getenv("PYAEDT_SERVER_AEDT_PATH", None):
|
|
669
|
-
return str(objects_lists)
|
|
670
|
-
else:
|
|
671
|
-
return objects_lists
|
|
672
|
-
|
|
673
381
|
def classify_nets(self, power_nets=None, signal_nets=None):
|
|
674
382
|
"""Reassign power/ground or signal nets based on list of nets.
|
|
675
383
|
|
|
@@ -701,85 +409,6 @@ class EdbNets(object):
|
|
|
701
409
|
self.nets[net].net_object.SetIsPowerGround(False)
|
|
702
410
|
return True
|
|
703
411
|
|
|
704
|
-
def plot(
|
|
705
|
-
self,
|
|
706
|
-
nets=None,
|
|
707
|
-
layers=None,
|
|
708
|
-
color_by_net=False,
|
|
709
|
-
show_legend=True,
|
|
710
|
-
save_plot=None,
|
|
711
|
-
outline=None,
|
|
712
|
-
size=(2000, 1000),
|
|
713
|
-
plot_components_on_top=False,
|
|
714
|
-
plot_components_on_bottom=False,
|
|
715
|
-
show=True,
|
|
716
|
-
title=None,
|
|
717
|
-
):
|
|
718
|
-
"""Plot a Net to Matplotlib 2D Chart.
|
|
719
|
-
|
|
720
|
-
Parameters
|
|
721
|
-
----------
|
|
722
|
-
nets : str, list, optional
|
|
723
|
-
Name of the net or list of nets to plot. If ``None`` all nets will be plotted.
|
|
724
|
-
layers : str, list, optional
|
|
725
|
-
Name of the layers to include in the plot. If ``None`` all the signal layers will be considered.
|
|
726
|
-
color_by_net : bool, optional
|
|
727
|
-
If ``True`` the plot will be colored by net.
|
|
728
|
-
If ``False`` the plot will be colored by layer. (default)
|
|
729
|
-
show_legend : bool, optional
|
|
730
|
-
If ``True`` the legend is shown in the plot. (default)
|
|
731
|
-
If ``False`` the legend is not shown.
|
|
732
|
-
save_plot : str, optional
|
|
733
|
-
If a path is specified the plot will be saved in this location.
|
|
734
|
-
If ``save_plot`` is provided, the ``show`` parameter is ignored.
|
|
735
|
-
outline : list, optional
|
|
736
|
-
List of points of the outline to plot.
|
|
737
|
-
size : tuple, int, optional
|
|
738
|
-
Image size in pixel (width, height). Default value is ``(2000, 1000)``
|
|
739
|
-
plot_components_on_top : bool, optional
|
|
740
|
-
If ``True`` the components placed on top layer are plotted.
|
|
741
|
-
If ``False`` the components are not plotted. (default)
|
|
742
|
-
If nets and/or layers is specified, only the components belonging to the specified nets/layers are plotted.
|
|
743
|
-
plot_components_on_bottom : bool, optional
|
|
744
|
-
If ``True`` the components placed on bottom layer are plotted.
|
|
745
|
-
If ``False`` the components are not plotted. (default)
|
|
746
|
-
If nets and/or layers is specified, only the components belonging to the specified nets/layers are plotted.
|
|
747
|
-
show : bool, optional
|
|
748
|
-
Whether to show the plot or not. Default is `True`.
|
|
749
|
-
"""
|
|
750
|
-
from pyedb.generic.plot import plot_matplotlib
|
|
751
|
-
|
|
752
|
-
object_lists = self.get_plot_data(
|
|
753
|
-
nets,
|
|
754
|
-
layers,
|
|
755
|
-
color_by_net,
|
|
756
|
-
outline,
|
|
757
|
-
plot_components_on_top,
|
|
758
|
-
plot_components_on_bottom,
|
|
759
|
-
)
|
|
760
|
-
|
|
761
|
-
if isinstance(size, int): # pragma: no cover
|
|
762
|
-
board_size_x, board_size_y = self._pedb.get_statistics().layout_size
|
|
763
|
-
fig_size_x = size
|
|
764
|
-
fig_size_y = board_size_y * fig_size_x / board_size_x
|
|
765
|
-
size = (fig_size_x, fig_size_y)
|
|
766
|
-
|
|
767
|
-
plot_title = title
|
|
768
|
-
if plot_title is None:
|
|
769
|
-
plot_title = self._pedb.active_cell.GetName()
|
|
770
|
-
|
|
771
|
-
return plot_matplotlib(
|
|
772
|
-
plot_data=object_lists,
|
|
773
|
-
size=size,
|
|
774
|
-
show_legend=show_legend,
|
|
775
|
-
xlabel="X (m)",
|
|
776
|
-
ylabel="Y (m)",
|
|
777
|
-
title=plot_title,
|
|
778
|
-
save_plot=save_plot,
|
|
779
|
-
axis_equal=True,
|
|
780
|
-
show=show,
|
|
781
|
-
)
|
|
782
|
-
|
|
783
412
|
def is_power_gound_net(self, netname_list):
|
|
784
413
|
"""Determine if one of the nets in a list is power or ground.
|
|
785
414
|
|
pyedb/generic/filesystem.py
CHANGED
|
@@ -116,13 +116,10 @@ class Scratch:
|
|
|
116
116
|
-------
|
|
117
117
|
|
|
118
118
|
"""
|
|
119
|
-
from distutils.dir_util import copy_tree
|
|
120
119
|
|
|
121
|
-
if destfolder:
|
|
122
|
-
copy_tree(src_folder, destfolder)
|
|
123
|
-
else:
|
|
120
|
+
if not destfolder:
|
|
124
121
|
destfolder = os.path.join(self.path, os.path.split(src_folder)[-1])
|
|
125
|
-
|
|
122
|
+
shutil.copytree(src_folder, destfolder, dirs_exist_ok=True)
|
|
126
123
|
return destfolder
|
|
127
124
|
|
|
128
125
|
def __enter__(self):
|