pyedb 0.39.1__py3-none-any.whl → 0.41.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.

@@ -22,8 +22,11 @@
22
22
 
23
23
  import re
24
24
 
25
- # from pyedb.generic.general_methods import generate_unique_name
26
- # from pyedb.grpc.database.primitive.padstack_instances import PadstackInstance
25
+ from ansys.edb.core.database import ProductIdType as GrpcProductIdType
26
+
27
+ from pyedb.generic.general_methods import generate_unique_name
28
+ from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
29
+
27
30
  # from pyedb.grpc.database.primitive.primitive import Primitive
28
31
 
29
32
 
@@ -120,146 +123,145 @@ class LayoutValidation:
120
123
  i.net = self._pedb.nets.nets[temp_name]
121
124
  return dc_shorts
122
125
 
123
- # def disjoint_nets(
124
- # self,
125
- # net_list=None,
126
- # keep_only_main_net=False,
127
- # clean_disjoints_less_than=0.0,
128
- # order_by_area=False,
129
- # keep_disjoint_pins=False,
130
- # ):
131
- # """Find and fix disjoint nets from a given netlist.
132
- #
133
- # Parameters
134
- # ----------
135
- # net_list : str, list, optional
136
- # List of nets on which check disjoints. If `None` is provided then the algorithm will loop on all nets.
137
- # keep_only_main_net : bool, optional
138
- # Remove all secondary nets other than principal one (the one with more objects in it). Default is `False`.
139
- # clean_disjoints_less_than : bool, optional
140
- # Clean all disjoint nets with area less than specified area in square meters. Default is `0.0` to disable it.
141
- # order_by_area : bool, optional
142
- # Whether if the naming order has to be by number of objects (fastest) or area (slowest but more accurate).
143
- # Default is ``False``.
144
- # keep_disjoint_pins : bool, optional
145
- # Whether if delete disjoints pins not connected to any other primitive or not. Default is ``False``.
146
- #
147
- # Returns
148
- # -------
149
- # List
150
- # New nets created.
151
- #
152
- # Examples
153
- # --------
154
- #
155
- # >>> renamed_nets = edb.layout_validation.disjoint_nets(["GND","Net2"])
156
- # """
157
- # from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
158
- # timer_start = self._pedb.logger.reset_timer()
159
- #
160
- # if not net_list:
161
- # net_list = list(self._pedb.nets.keys())
162
- # elif isinstance(net_list, str):
163
- # net_list = [net_list]
164
- # _objects_list = {}
165
- # _padstacks_list = {}
166
- # for prim in self._pedb.modeler.primitives:
167
- # if not prim.net.is_null:
168
- # n_name = prim.net.name
169
- # if n_name in _objects_list:
170
- # _objects_list[n_name].append(prim)
171
- # else:
172
- # _objects_list[n_name] = [prim]
173
- # for pad in list(self._pedb.padstacks.instances.values()):
174
- # if not pad.net.is_null:
175
- # n_name = pad.net_name
176
- # if n_name in _padstacks_list:
177
- # _padstacks_list[n_name].append(pad)
178
- # else:
179
- # _padstacks_list[n_name] = [pad]
180
- # new_nets = []
181
- # disjoints_objects = []
182
- # self._pedb.logger.reset_timer()
183
- # for net in net_list:
184
- # net_groups = []
185
- # obj_dict = {}
186
- # for i in _objects_list.get(net, []):
187
- # obj_dict[i.id] = i
188
- # for i in _padstacks_list.get(net, []):
189
- # obj_dict[i.id] = i
190
- # objs = list(obj_dict.values())
191
- # l = len(objs)
192
- # while l > 0:
193
- # l1 = self._layout_instance.get_connected_objects(objs[0].layout_object_instance, False)
194
- # l1.append(objs[0].id)
195
- # repetition = False
196
- # for net_list in net_groups:
197
- # if set(l1).intersection(net_list):
198
- # net_groups.append([i for i in l1 if i not in net_list])
199
- # repetition = True
200
- # if not repetition:
201
- # net_groups.append(l1)
202
- # objs = [i for i in objs if i.id not in l1]
203
- # l = len(objs)
204
- # if len(net_groups) > 1:
205
- #
206
- # def area_calc(elem):
207
- # sum = 0
208
- # for el in elem:
209
- # try:
210
- # if el.layout_obj.obj_type.value == 0:
211
- # if not el.is_void:
212
- # sum += el.area()
213
- # except:
214
- # pass
215
- # return sum
216
- #
217
- # if order_by_area:
218
- # areas = [area_calc(i) for i in net_groups]
219
- # sorted_list = [x for _, x in sorted(zip(areas, net_groups), reverse=True)]
220
- # else:
221
- # sorted_list = sorted(net_groups, key=len, reverse=True)
222
- # for disjoints in sorted_list[1:]:
223
- # if keep_only_main_net:
224
- # for geo in disjoints:
225
- # try:
226
- # obj_dict[geo].delete()
227
- # except KeyError:
228
- # pass
229
- # elif len(disjoints) == 1 and (
230
- # clean_disjoints_less_than
231
- # and "area" in dir(obj_dict[disjoints[0]])
232
- # and obj_dict[disjoints[0]].area() < clean_disjoints_less_than
233
- # ):
234
- # try:
235
- # obj_dict[disjoints[0]].delete()
236
- # except KeyError:
237
- # pass
238
- # elif (
239
- # len(disjoints) == 1
240
- # and not keep_disjoint_pins
241
- # and isinstance(obj_dict[disjoints[0]], PadstackInstance)
242
- # ):
243
- # try:
244
- # obj_dict[disjoints[0]].delete()
245
- # except KeyError:
246
- # pass
247
- #
248
- # else:
249
- # new_net_name = generate_unique_name(net, n=6)
250
- # net_obj = self._pedb.nets.find_or_create_net(new_net_name)
251
- # if net_obj:
252
- # new_nets.append(net_obj.name)
253
- # for geo in disjoints:
254
- # try:
255
- # obj_dict[geo].net_name = net_obj.name
256
- # except KeyError:
257
- # pass
258
- # disjoints_objects.extend(disjoints)
259
- # self._pedb._logger.info("Found {} objects in {} new nets.".format(len(disjoints_objects), len(new_nets)))
260
- # self._pedb._logger.info_timer("Disjoint Cleanup Completed.", timer_start)
261
- #
262
- # return new_nets
126
+ def disjoint_nets(
127
+ self,
128
+ net_list=None,
129
+ keep_only_main_net=False,
130
+ clean_disjoints_less_than=0.0,
131
+ order_by_area=False,
132
+ keep_disjoint_pins=False,
133
+ ):
134
+ """Find and fix disjoint nets from a given netlist.
135
+
136
+ Parameters
137
+ ----------
138
+ net_list : str, list, optional
139
+ List of nets on which check disjoints. If `None` is provided then the algorithm will loop on all nets.
140
+ keep_only_main_net : bool, optional
141
+ Remove all secondary nets other than principal one (the one with more objects in it). Default is `False`.
142
+ clean_disjoints_less_than : bool, optional
143
+ Clean all disjoint nets with area less than specified area in square meters. Default is `0.0` to disable it.
144
+ order_by_area : bool, optional
145
+ Whether if the naming order has to be by number of objects (fastest) or area (slowest but more accurate).
146
+ Default is ``False``.
147
+ keep_disjoint_pins : bool, optional
148
+ Whether if delete disjoints pins not connected to any other primitive or not. Default is ``False``.
149
+
150
+ Returns
151
+ -------
152
+ List
153
+ New nets created.
154
+
155
+ Examples
156
+ --------
157
+
158
+ >>> renamed_nets = edb.layout_validation.disjoint_nets(["GND","Net2"])
159
+ """
160
+ timer_start = self._pedb.logger.reset_timer()
161
+
162
+ if not net_list:
163
+ net_list = list(self._pedb.nets.keys())
164
+ elif isinstance(net_list, str):
165
+ net_list = [net_list]
166
+ _objects_list = {}
167
+ _padstacks_list = {}
168
+ for prim in self._pedb.modeler.primitives:
169
+ if not prim.net.is_null:
170
+ n_name = prim.net.name
171
+ if n_name in _objects_list:
172
+ _objects_list[n_name].append(prim)
173
+ else:
174
+ _objects_list[n_name] = [prim]
175
+ for pad in list(self._pedb.padstacks.instances.values()):
176
+ if not pad.net.is_null:
177
+ n_name = pad.net_name
178
+ if n_name in _padstacks_list:
179
+ _padstacks_list[n_name].append(pad)
180
+ else:
181
+ _padstacks_list[n_name] = [pad]
182
+ new_nets = []
183
+ disjoints_objects = []
184
+ self._pedb.logger.reset_timer()
185
+ for net in net_list:
186
+ net_groups = []
187
+ obj_dict = {}
188
+ for i in _objects_list.get(net, []):
189
+ obj_dict[i.id] = i
190
+ for i in _padstacks_list.get(net, []):
191
+ obj_dict[i.id] = i
192
+ objs = list(obj_dict.values())
193
+ l = len(objs)
194
+ while l > 0:
195
+ l1 = self._layout_instance.get_connected_objects(objs[0].layout_object_instance, False)
196
+ l1.append(objs[0].id)
197
+ repetition = False
198
+ for net_list in net_groups:
199
+ if set(l1).intersection(net_list):
200
+ net_groups.append([i for i in l1 if i not in net_list])
201
+ repetition = True
202
+ if not repetition:
203
+ net_groups.append(l1)
204
+ objs = [i for i in objs if i.id not in l1]
205
+ l = len(objs)
206
+ if len(net_groups) > 1:
207
+
208
+ def area_calc(elem):
209
+ sum = 0
210
+ for el in elem:
211
+ try:
212
+ if el.layout_obj.obj_type.value == 0:
213
+ if not el.is_void:
214
+ sum += el.area()
215
+ except:
216
+ pass
217
+ return sum
218
+
219
+ if order_by_area:
220
+ areas = [area_calc(i) for i in net_groups]
221
+ sorted_list = [x for _, x in sorted(zip(areas, net_groups), reverse=True)]
222
+ else:
223
+ sorted_list = sorted(net_groups, key=len, reverse=True)
224
+ for disjoints in sorted_list[1:]:
225
+ if keep_only_main_net:
226
+ for geo in disjoints:
227
+ try:
228
+ obj_dict[geo].delete()
229
+ except KeyError:
230
+ pass
231
+ elif len(disjoints) == 1 and (
232
+ clean_disjoints_less_than
233
+ and "area" in dir(obj_dict[disjoints[0]])
234
+ and obj_dict[disjoints[0]].area() < clean_disjoints_less_than
235
+ ):
236
+ try:
237
+ obj_dict[disjoints[0]].delete()
238
+ except KeyError:
239
+ pass
240
+ elif (
241
+ len(disjoints) == 1
242
+ and not keep_disjoint_pins
243
+ and isinstance(obj_dict[disjoints[0]], PadstackInstance)
244
+ ):
245
+ try:
246
+ obj_dict[disjoints[0]].delete()
247
+ except KeyError:
248
+ pass
249
+
250
+ else:
251
+ new_net_name = generate_unique_name(net, n=6)
252
+ net_obj = self._pedb.nets.find_or_create_net(new_net_name)
253
+ if net_obj:
254
+ new_nets.append(net_obj.name)
255
+ for geo in disjoints:
256
+ try:
257
+ obj_dict[geo].net_name = net_obj.name
258
+ except KeyError:
259
+ pass
260
+ disjoints_objects.extend(disjoints)
261
+ self._pedb._logger.info("Found {} objects in {} new nets.".format(len(disjoints_objects), len(new_nets)))
262
+ self._pedb._logger.info_timer("Disjoint Cleanup Completed.", timer_start)
263
+
264
+ return new_nets
263
265
 
264
266
  def fix_self_intersections(self, net_list=None):
265
267
  """Find and fix self intersections from a given netlist.
@@ -274,7 +276,7 @@ class LayoutValidation:
274
276
  bool
275
277
  """
276
278
  if not net_list:
277
- net_list = list(self._pedb.nets.keys())
279
+ net_list = list(self._pedb.nets.nets.keys())
278
280
  elif isinstance(net_list, str):
279
281
  net_list = [net_list]
280
282
  new_prims = []
@@ -317,3 +319,22 @@ class LayoutValidation:
317
319
  v.rlc_values = [0, 1, 0]
318
320
  self._pedb._logger.info(f"Found {len(temp)} inductors have no value.")
319
321
  return
322
+
323
+ def padstacks_no_name(self, fix=False):
324
+ pds = self._pedb.layout.padstack_instances
325
+ counts = 0
326
+ via_count = 1
327
+ for obj in pds:
328
+ name = obj.get_product_property(GrpcProductIdType.DESIGNER, 11)
329
+ name = str(name).strip("'")
330
+ if name == "":
331
+ counts += 1
332
+ if fix:
333
+ if not obj.component:
334
+ obj.set_product_property(GrpcProductIdType.DESIGNER, 11, f"Via{via_count}")
335
+ via_count = via_count + 1
336
+ else:
337
+ obj.set_product_property(
338
+ GrpcProductIdType.DESIGNER, 11, f"{obj.component.name}-{obj.component_pin}"
339
+ )
340
+ self._pedb._logger.info(f"Found {counts}/{len(pds)} padstacks have no name.")
@@ -122,13 +122,7 @@ class Net(GrpcNet):
122
122
  return self._pedb.layout_validation.dc_shorts(self.name, fix)
123
123
 
124
124
  def plot(
125
- self,
126
- layers=None,
127
- show_legend=True,
128
- save_plot=None,
129
- outline=None,
130
- size=(2000, 1000),
131
- show=True,
125
+ self, layers=None, show_legend=True, save_plot=None, outline=None, size=(2000, 1000), show=True, title=None
132
126
  ):
133
127
  """Plot a net to Matplotlib 2D chart.
134
128
 
@@ -147,7 +141,9 @@ class Net(GrpcNet):
147
141
  size : tuple, optional
148
142
  Image size in pixel (width, height).
149
143
  show : bool, optional
150
- Whether to show the plot or not. Default is `True`.
144
+ Whether to show the plot or not. Default is ``True``.
145
+ title : str, optional
146
+ Plot title. If value is ``None`` the project name is assigned by default. Default value is ``None``.
151
147
  """
152
148
 
153
149
  self._pedb.nets.plot(
@@ -160,6 +156,7 @@ class Net(GrpcNet):
160
156
  show=show,
161
157
  plot_components=True,
162
158
  plot_vias=True,
159
+ title=None,
163
160
  )
164
161
 
165
162
  def get_smallest_trace_width(self):