pyedb 0.34.3__py3-none-any.whl → 0.36.0__py3-none-any.whl

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

Potentially problematic release.


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

pyedb/__init__.py CHANGED
@@ -44,7 +44,7 @@ deprecation_warning()
44
44
  #
45
45
 
46
46
  pyedb_path = os.path.dirname(__file__)
47
- __version__ = "0.34.3"
47
+ __version__ = "0.36.0"
48
48
  version = __version__
49
49
 
50
50
  #
@@ -210,10 +210,10 @@ class CfgComponent(CfgBase):
210
210
  self._pyedb_obj.component_property = cp
211
211
 
212
212
  def set_parameters_to_edb(self):
213
- if self.enabled:
214
- self._pyedb_obj.enabled = self.enabled
215
213
  if self.type:
216
214
  self._pyedb_obj.type = self.type
215
+ if self.enabled:
216
+ self._pyedb_obj.enabled = self.enabled
217
217
 
218
218
  self._set_model_properties_to_edb()
219
219
  if self._pyedb_obj.type.lower() == "ic":
@@ -97,6 +97,7 @@ class CfgModeler:
97
97
  for p in self.padstack_instances:
98
98
  p_inst = self._pedb.padstacks.place(
99
99
  via_name=p.name,
100
+ net_name=p.net_name,
100
101
  position=p.position,
101
102
  definition_name=p.definition,
102
103
  )
@@ -124,6 +124,15 @@ class CfgPadstackDefinition(CfgBase):
124
124
  if self.solder_ball_parameters:
125
125
  self._set_solder_parameters_to_edb(self.solder_ball_parameters)
126
126
 
127
+ def retrieve_parameters_from_edb(self):
128
+ self.name = self._pyedb_obj.name
129
+ self.hole_plating_thickness = self._pyedb_obj.hole_plating_thickness
130
+ self.material = self._pyedb_obj.material
131
+ self.hole_range = self._pyedb_obj.hole_range
132
+ self.pad_parameters = self._get_pad_parameters_from_edb()
133
+ self.hole_parameters = self._get_hole_parameters_from_edb()
134
+ self.solder_ball_parameters = self._get_solder_parameters_from_edb()
135
+
127
136
  def _set_solder_parameters_to_edb(self, parameters):
128
137
  pdef_data = self._pyedb_obj._padstack_def_data
129
138
 
@@ -158,15 +167,6 @@ class CfgPadstackDefinition(CfgBase):
158
167
  }
159
168
  return parameters
160
169
 
161
- def retrieve_parameters_from_edb(self):
162
- self.name = self._pyedb_obj.name
163
- self.hole_plating_thickness = self._pyedb_obj.hole_plating_thickness
164
- self.material = self._pyedb_obj.material
165
- self.hole_range = self._pyedb_obj.hole_range
166
- self.pad_parameters = self._get_pad_parameters_from_edb()
167
- self.hole_parameters = self._get_hole_parameters_from_edb()
168
- self.solder_ball_parameters = self._get_solder_parameters_from_edb()
169
-
170
170
  def _get_pad_parameters_from_edb(self):
171
171
  """Pad parameters.
172
172
 
@@ -67,17 +67,16 @@ class CfgPinGroup(CfgBase):
67
67
  def create(self):
68
68
  """Apply pin group on layout."""
69
69
  if self.pins:
70
- self._pedb.siwave.create_pin_group(self.reference_designator, list(self.pins), self.name)
70
+ pins = self.pins if isinstance(self.pins, list) else [self.pins]
71
+ self._pedb.siwave.create_pin_group(self.reference_designator, pins, self.name)
71
72
  elif self.net:
72
- if self.reference_designator in self._pedb.components.instances:
73
- comp = self._pedb.components.instances[self.reference_designator]
74
- else:
75
- raise f"Component not found for creating pin group {self.name}."
76
- pins = [p for p, obj in comp.pins.items() if obj.net_name in self.net]
73
+ nets = self.net if isinstance(self.net, list) else [self.net]
74
+ comp = self._pedb.components.instances[self.reference_designator]
75
+ pins = [p for p, obj in comp.pins.items() if obj.net_name in nets]
77
76
  if not self._pedb.siwave.create_pin_group(self.reference_designator, pins, self.name):
78
- self._pedb.logger.error(f"Failed to create pin group {self.name}")
77
+ raise RuntimeError(f"Failed to create pin group {self.name}")
79
78
  else:
80
- self._pedb.logger.error(f"No net and pins defined for defining pin group {self.name}")
79
+ raise RuntimeError(f"No net and pins defined for defining pin group {self.name}")
81
80
 
82
81
  def export_properties(self):
83
82
  if self.pins:
@@ -46,6 +46,7 @@ class CfgCoordianteTerminalInfo(CfgTerminalInfo):
46
46
  self.point_x = self.value["point"][0]
47
47
  self.point_y = self.value["point"][1]
48
48
  self.net = self.value["net"]
49
+ self.contact_radius = self.value.get("contact_radius", None)
49
50
 
50
51
  def export_properties(self):
51
52
  return {"coordinates": {"layer": self.layer, "point": [self.point_x, self.point_y], "net": self.net}}
@@ -244,6 +245,9 @@ class CfgCircuitElement(CfgBase):
244
245
  point = [self.positive_terminal_info.point_x, self.positive_terminal_info.point_y]
245
246
  net_name = self.positive_terminal_info.net
246
247
  pos_coor_terminal[self.name] = self._pedb.get_point_terminal(self.name, net_name, point, layer)
248
+ if self.positive_terminal_info.contact_radius:
249
+ pos_coor_terminal[self.name].contact_radius = self.positive_terminal_info.contact_radius
250
+
247
251
  elif pos_type == "pin_group":
248
252
  if self.distributed:
249
253
  pins = self._get_pins(pos_type, pos_value)
@@ -265,7 +269,7 @@ class CfgCircuitElement(CfgBase):
265
269
  pins = {pos_value: self._pedb.components.instances[self.reference_designator].pins[pos_value]}
266
270
  pos_objs.update(pins)
267
271
  else:
268
- raise f"Wrong positive terminal type {pos_type}"
272
+ raise Exception(f"Wrong positive terminal type {pos_type}.")
269
273
 
270
274
  self.pos_terminals = {i: j.create_terminal(i) for i, j in pos_objs.items()}
271
275
  self.pos_terminals.update(pos_coor_terminal)
@@ -276,7 +280,7 @@ class CfgCircuitElement(CfgBase):
276
280
 
277
281
  if neg_type == "coordinates":
278
282
  layer = self.negative_terminal_info.layer
279
- point = [self.negative_terminal_info.point_x, self.positive_terminal_info.point_y]
283
+ point = [self.negative_terminal_info.point_x, self.negative_terminal_info.point_y]
280
284
  net_name = self.negative_terminal_info.net
281
285
  self.neg_terminal = self._pedb.get_point_terminal(self.name + "_ref", net_name, point, layer)
282
286
  elif neg_type == "nearest_pin":
@@ -297,9 +301,12 @@ class CfgCircuitElement(CfgBase):
297
301
  # create pin group
298
302
  neg_obj = self._create_pin_group(pins, True)
299
303
  elif neg_type == "pin":
300
- neg_obj = {neg_value: self._pedb.components.instances[self.reference_designator].pins[neg_value]}
304
+ terminal_name = f"{self.reference_designator}_{neg_value}"
305
+ neg_obj = {
306
+ terminal_name: self._pedb.components.instances[self.reference_designator].pins[neg_value]
307
+ }
301
308
  else:
302
- raise f"Wrong negative terminal type {neg_type}"
309
+ raise Exception(f"Wrong negative terminal type {neg_type}.")
303
310
  self.neg_terminal = [
304
311
  j.create_terminal(i) if not j.terminal else j.terminal for i, j in neg_obj.items()
305
312
  ][0]
@@ -375,6 +382,7 @@ class CfgSource(CfgCircuitElement):
375
382
  super().__init__(pedb, **kwargs)
376
383
 
377
384
  self.magnitude = kwargs.get("magnitude", 0.001)
385
+ self.equipotential = kwargs.get("equipotential", False)
378
386
 
379
387
  def set_parameters_to_edb(self):
380
388
  """Create sources."""
@@ -394,6 +402,33 @@ class CfgSource(CfgCircuitElement):
394
402
  elem.name = f"{self.name}_{elem.name}"
395
403
  elem.magnitude = self.magnitude / self._elem_num
396
404
  circuit_elements.append(elem)
405
+ for terminal in circuit_elements:
406
+ if self.equipotential:
407
+ terms = [terminal, terminal.ref_terminal] if terminal.ref_terminal else [terminal]
408
+ for t in terms:
409
+ pads = []
410
+ if t.terminal_type == "PadstackInstanceTerminal":
411
+ pads.append(t.reference_object)
412
+ t._edb_object.dcir_equipotential_region = True
413
+ elif t.terminal_type == "PinGroupTerminal":
414
+ name = t._edb_object.GetPinGroup().GetName()
415
+ pg = self._pedb.siwave.pin_groups[name]
416
+ pads.extend([i for _, i in pg.pins.items()])
417
+ elif t.terminal_type == "PointTerminal":
418
+ temp = [i for i in self._pedb.layout.terminals if i.name == t.name][0]
419
+ if not temp.is_reference_terminal:
420
+ radius = self.positive_terminal_info.contact_radius
421
+ else:
422
+ radius = self.negative_terminal_info.contact_radius
423
+ if radius is not None:
424
+ prim = self._pedb.modeler.create_circle(
425
+ temp.layer.name, temp.location[0], temp.location[1], radius, temp.net_name
426
+ )
427
+ prim.dcir_equipotential_region = True
428
+
429
+ for i in pads:
430
+ i._set_equipotential()
431
+
397
432
  return circuit_elements
398
433
 
399
434
  def export_properties(self):
@@ -45,6 +45,7 @@ class CfgLayer(CfgBase):
45
45
  self.fill_material = kwargs.get("fill_material", None)
46
46
  self.thickness = kwargs.get("thickness", None)
47
47
  self.roughness = kwargs.get("roughness", None)
48
+ self.etching = kwargs.get("etching", None)
48
49
 
49
50
 
50
51
  class CfgStackup:
@@ -134,13 +134,17 @@ class Configuration:
134
134
 
135
135
  # Configure stackup
136
136
  if kwargs.get("fix_padstack_def"):
137
+ from pyedb.configuration.cfg_padstacks import CfgPadstackDefinition
138
+
137
139
  pedb_defs = self._pedb.padstacks.definitions
138
- temp = {}
139
- for name, pdef in pedb_defs.items():
140
- temp[name] = pdef.get_properties()
140
+ temp = []
141
+ for _, pdef in pedb_defs.items():
142
+ cfg_def = CfgPadstackDefinition(self._pedb, pdef)
143
+ cfg_def.retrieve_parameters_from_edb()
144
+ temp.append(cfg_def)
141
145
  self.cfg_data.stackup.apply()
142
- for name, pdef_p in temp.items():
143
- pedb_defs[name].set_properties(**pdef_p)
146
+ for cfg_pdef in temp:
147
+ cfg_pdef.set_parameters_to_edb()
144
148
  else:
145
149
  self.cfg_data.stackup.apply()
146
150
 
pyedb/dotnet/edb.py CHANGED
@@ -603,7 +603,7 @@ class Edb(Database):
603
603
  def import_layout_pcb(
604
604
  self,
605
605
  input_file,
606
- working_dir,
606
+ working_dir="",
607
607
  anstranslator_full_path="",
608
608
  use_ppe=False,
609
609
  control_file=None,
@@ -616,7 +616,7 @@ class Edb(Database):
616
616
  ----------
617
617
  input_file : str
618
618
  Full path to the board file.
619
- working_dir : str
619
+ working_dir : str, optional
620
620
  Directory in which to create the ``aedb`` folder. The name given to the AEDB file
621
621
  is the same as the name of the board file.
622
622
  anstranslator_full_path : str, optional
@@ -1510,6 +1510,13 @@ class Edb(Database):
1510
1510
  else:
1511
1511
  return False
1512
1512
  else:
1513
+ if anstranslator_full_path and os.path.exists(anstranslator_full_path):
1514
+ path = anstranslator_full_path
1515
+ else:
1516
+ path = os.path.join(self.base_path, "anstranslator")
1517
+ if is_windows:
1518
+ path += ".exe"
1519
+
1513
1520
  temp_map_file = os.path.splitext(inputGDS)[0] + ".map"
1514
1521
  temp_layermap_file = os.path.splitext(inputGDS)[0] + ".layermap"
1515
1522
 
@@ -1529,10 +1536,10 @@ class Edb(Database):
1529
1536
  else:
1530
1537
  self.logger.error("Unable to define control file.")
1531
1538
 
1532
- command = [anstranslator_full_path, inputGDS, f'-g="{map_file}"', f'-c="{control_file}"']
1539
+ command = [path, inputGDS, f'-g="{map_file}"', f'-c="{control_file}"']
1533
1540
  else:
1534
1541
  command = [
1535
- anstranslator_full_path,
1542
+ path,
1536
1543
  inputGDS,
1537
1544
  f'-o="{control_file_temp}"' f'-t="{tech_file}"',
1538
1545
  f'-g="{map_file}"',
@@ -4564,6 +4571,7 @@ class Edb(Database):
4564
4571
  port_poly = cloned_edb.modeler.create_polygon(
4565
4572
  main_shape=void_info[0].polygon_data._edb_object, layer_name="ref", net_name="GND"
4566
4573
  )
4574
+ port_poly.scale(1.1)
4567
4575
  pec_poly = cloned_edb.modeler.create_polygon(
4568
4576
  main_shape=port_poly.polygon_data._edb_object, layer_name="port_pec", net_name="GND"
4569
4577
  )
@@ -66,7 +66,7 @@ class PinPair(object): # pragma: no cover
66
66
  @resistance.setter
67
67
  def resistance(self, value):
68
68
  self._pin_pair_rlc.R = value
69
- self._set_comp_prop(self._pin_pair_rlc) # pragma: no cover
69
+ self._set_comp_prop() # pragma: no cover
70
70
 
71
71
  @property
72
72
  def inductance(self):
@@ -75,7 +75,7 @@ class PinPair(object): # pragma: no cover
75
75
  @inductance.setter
76
76
  def inductance(self, value):
77
77
  self._pin_pair_rlc.L = value
78
- self._set_comp_prop(self._pin_pair_rlc) # pragma: no cover
78
+ self._set_comp_prop() # pragma: no cover
79
79
 
80
80
  @property
81
81
  def capacitance(self):
@@ -84,7 +84,7 @@ class PinPair(object): # pragma: no cover
84
84
  @capacitance.setter
85
85
  def capacitance(self, value):
86
86
  self._pin_pair_rlc.C = value
87
- self._set_comp_prop(self._pin_pair_rlc) # pragma: no cover
87
+ self._set_comp_prop() # pragma: no cover
88
88
 
89
89
  @property
90
90
  def rlc_values(self): # pragma: no cover
@@ -19,6 +19,7 @@
19
19
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
+ import re
22
23
 
23
24
  from pyedb.dotnet.edb_core.cell.connectable import Connectable
24
25
  from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
@@ -787,3 +788,66 @@ class Primitive(Connectable):
787
788
  self.polygon_data = polygon_data
788
789
  return True
789
790
  return False
791
+
792
+ @property
793
+ def _em_properties(self):
794
+ """Get EM properties."""
795
+ default = (
796
+ r"$begin 'EM properties'\n"
797
+ r"\tType('Mesh')\n"
798
+ r"\tDataId='EM properties1'\n"
799
+ r"\t$begin 'Properties'\n"
800
+ r"\t\tGeneral=''\n"
801
+ r"\t\tModeled='true'\n"
802
+ r"\t\tUnion='true'\n"
803
+ r"\t\t'Use Precedence'='false'\n"
804
+ r"\t\t'Precedence Value'='1'\n"
805
+ r"\t\tPlanarEM=''\n"
806
+ r"\t\tRefined='true'\n"
807
+ r"\t\tRefineFactor='1'\n"
808
+ r"\t\tNoEdgeMesh='false'\n"
809
+ r"\t\tHFSS=''\n"
810
+ r"\t\t'Solve Inside'='false'\n"
811
+ r"\t\tSIwave=''\n"
812
+ r"\t\t'DCIR Equipotential Region'='false'\n"
813
+ r"\t$end 'Properties'\n"
814
+ r"$end 'EM properties'\n"
815
+ )
816
+
817
+ pid = self._pedb.edb_api.ProductId.Designer
818
+ _, p = self._edb_object.GetProductProperty(pid, 18, "")
819
+ if p:
820
+ return p
821
+ else:
822
+ return default
823
+
824
+ @_em_properties.setter
825
+ def _em_properties(self, em_prop):
826
+ """Set EM properties"""
827
+ pid = self._pedb.edb_api.ProductId.Designer
828
+ self._edb_object.SetProductProperty(pid, 18, em_prop)
829
+
830
+ @property
831
+ def dcir_equipotential_region(self):
832
+ """Check whether dcir equipotential region is enabled.
833
+
834
+ Returns
835
+ -------
836
+ bool
837
+ """
838
+ pattern = r"'DCIR Equipotential Region'='([^']+)'"
839
+ em_pp = self._em_properties
840
+ result = re.search(pattern, em_pp).group(1)
841
+ if result == "true":
842
+ return True
843
+ else:
844
+ return False
845
+
846
+ @dcir_equipotential_region.setter
847
+ def dcir_equipotential_region(self, value):
848
+ """Set dcir equipotential region."""
849
+ pp = r"'DCIR Equipotential Region'='true'" if value else r"'DCIR Equipotential Region'='false'"
850
+ em_pp = self._em_properties
851
+ pattern = r"'DCIR Equipotential Region'='([^']+)'"
852
+ new_em_pp = re.sub(pattern, pp, em_pp)
853
+ self._em_properties = new_em_pp
@@ -101,3 +101,15 @@ class PadstackInstanceTerminal(Terminal):
101
101
  def padstack_instance(self):
102
102
  p_inst, _ = self._get_parameters()
103
103
  return self._pedb.layout.find_object_by_id(p_inst.GetId())
104
+
105
+ @property
106
+ def layer(self):
107
+ """Get layer of the terminal."""
108
+ _, _, layer = self._edb_object.GetParameters()
109
+ return self._pedb.stackup.all_layers[layer.GetName()]
110
+
111
+ @layer.setter
112
+ def layer(self, value):
113
+ layer = self._pedb.stackup.layers[value]._edb_layer
114
+ point_data = self._pedb.point_data(*self.location)
115
+ self._edb_object.SetParameters(point_data, layer)
@@ -66,3 +66,15 @@ class PointTerminal(Terminal):
66
66
  raise Exception(msg)
67
67
  else:
68
68
  return terminal
69
+
70
+ @property
71
+ def layer(self):
72
+ """Get layer of the terminal."""
73
+ _, _, layer = self._edb_object.GetParameters()
74
+ return self._pedb.stackup.all_layers[layer.GetName()]
75
+
76
+ @layer.setter
77
+ def layer(self, value):
78
+ layer = self._pedb.stackup.layers[value]._edb_layer
79
+ point_data = self._pedb.point_data(*self.location)
80
+ self._edb_object.SetParameters(point_data, layer)
@@ -105,25 +105,16 @@ class Terminal(Connectable):
105
105
  @property
106
106
  def layer(self):
107
107
  """Get layer of the terminal."""
108
- point_data = self._pedb.point_data(0, 0)
109
- layer = list(self._pedb.stackup.layers.values())[0]._edb_layer
110
- if self._edb_object.GetParameters(point_data, layer):
111
- return self._pedb.stackup.all_layers[layer.GetName()]
112
- else:
113
- self._pedb.logger.warning(f"No pad parameters found for terminal {self.name}")
114
-
115
- @layer.setter
116
- def layer(self, value):
117
- layer = self._pedb.stackup.layers[value]._edb_layer
118
- point_data = self._pedb.point_data(*self.location)
119
- self._edb_object.SetParameters(point_data, layer)
108
+ return self._pedb.logger.error("Cannot determine terminal layer")
120
109
 
121
110
  @property
122
111
  def location(self):
123
112
  """Location of the terminal."""
124
- layer = list(self._pedb.stackup.layers.values())[0]._edb_layer
125
- _, point_data, _ = self._edb_object.GetParameters(None, layer)
126
- return [point_data.X.ToDouble(), point_data.Y.ToDouble()]
113
+ try:
114
+ _, point_data, _ = self._edb_object.GetParameters()
115
+ return [point_data.X.ToDouble(), point_data.Y.ToDouble()]
116
+ except:
117
+ self._pedb.logger.error("Cannot determine terminal location")
127
118
 
128
119
  @location.setter
129
120
  def location(self, value):
@@ -111,16 +111,9 @@ class Components(object):
111
111
 
112
112
  def __init__(self, p_edb):
113
113
  self._pedb = p_edb
114
- self._cmp = {}
115
- self._res = {}
116
- self._cap = {}
117
- self._ind = {}
118
- self._ios = {}
119
- self._ics = {}
120
- self._others = {}
114
+ self.refresh_components()
121
115
  self._pins = {}
122
116
  self._comps_by_part = {}
123
- self._init_parts()
124
117
  self._padstack = EdbPadstacks(self._pedb)
125
118
 
126
119
  @property
@@ -132,16 +125,6 @@ class Components(object):
132
125
  def _edb(self):
133
126
  return self._pedb.edb_api
134
127
 
135
- def _init_parts(self):
136
- a = self.instances
137
- a = self.resistors
138
- a = self.ICs
139
- a = self.Others
140
- a = self.inductors
141
- a = self.IOs
142
- a = self.components_by_partname
143
- return True
144
-
145
128
  def _get_edb_value(self, value):
146
129
  return self._pedb.edb_value(value)
147
130
 
@@ -205,8 +188,6 @@ class Components(object):
205
188
  >>> edbapp.components.instances
206
189
 
207
190
  """
208
- if not self._cmp:
209
- self.refresh_components()
210
191
  return self._cmp
211
192
 
212
193
  @property
@@ -310,10 +291,29 @@ class Components(object):
310
291
 
311
292
  def refresh_components(self):
312
293
  """Refresh the component dictionary."""
313
- # self._logger.info("Refreshing the Components dictionary.")
314
294
  self._cmp = {}
295
+ self._res = {}
296
+ self._ind = {}
297
+ self._cap = {}
298
+ self._ics = {}
299
+ self._ios = {}
300
+ self._others = {}
315
301
  for i in self._pedb.layout.groups:
316
302
  self._cmp[i.name] = i
303
+ if i.type == "Resistor":
304
+ self._res[i.name] = i
305
+ elif i.type == "Capacitor":
306
+ self._cap[i.name] = i
307
+ elif i.type == "Inductor":
308
+ self._ind[i.name] = i
309
+ elif i.type == "IC":
310
+ self._ics[i.name] = i
311
+ elif i.type == "IO":
312
+ self._ios[i.name] = i
313
+ elif i.type == "Other":
314
+ self._others[i.name] = i
315
+ else:
316
+ self._logger.warning(f"Unknown component type {i.name} found while refreshing components, will ignore")
317
317
  return True
318
318
 
319
319
  @property
@@ -332,10 +332,6 @@ class Components(object):
332
332
  >>> edbapp = Edb("myaedbfolder")
333
333
  >>> edbapp.components.resistors
334
334
  """
335
- self._res = {}
336
- for el, val in self.instances.items():
337
- if val.type == "Resistor":
338
- self._res[el] = val
339
335
  return self._res
340
336
 
341
337
  @property
@@ -354,10 +350,6 @@ class Components(object):
354
350
  >>> edbapp = Edb("myaedbfolder")
355
351
  >>> edbapp.components.capacitors
356
352
  """
357
- self._cap = {}
358
- for el, val in self.instances.items():
359
- if val.type == "Capacitor":
360
- self._cap[el] = val
361
353
  return self._cap
362
354
 
363
355
  @property
@@ -377,10 +369,6 @@ class Components(object):
377
369
  >>> edbapp.components.inductors
378
370
 
379
371
  """
380
- self._ind = {}
381
- for el, val in self.instances.items():
382
- if val.type == "Inductor":
383
- self._ind[el] = val
384
372
  return self._ind
385
373
 
386
374
  @property
@@ -400,10 +388,6 @@ class Components(object):
400
388
  >>> edbapp.components.ICs
401
389
 
402
390
  """
403
- self._ics = {}
404
- for el, val in self.instances.items():
405
- if val.type == "IC":
406
- self._ics[el] = val
407
391
  return self._ics
408
392
 
409
393
  @property
@@ -423,10 +407,6 @@ class Components(object):
423
407
  >>> edbapp.components.IOs
424
408
 
425
409
  """
426
- self._ios = {}
427
- for el, val in self.instances.items():
428
- if val.type == "IO":
429
- self._ios[el] = val
430
410
  return self._ios
431
411
 
432
412
  @property
@@ -446,10 +426,6 @@ class Components(object):
446
426
  >>> edbapp.components.others
447
427
 
448
428
  """
449
- self._others = {}
450
- for el, val in self.instances.items():
451
- if val.type == "Other":
452
- self._others[el] = val
453
429
  return self._others
454
430
 
455
431
  @property