pyedb 0.38.0__py3-none-any.whl → 0.39.0__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (205) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/common/nets.py +53 -139
  3. pyedb/configuration/cfg_components.py +1 -1
  4. pyedb/configuration/cfg_general.py +4 -2
  5. pyedb/configuration/cfg_modeler.py +1 -1
  6. pyedb/configuration/cfg_package_definition.py +1 -1
  7. pyedb/configuration/cfg_padstacks.py +1 -1
  8. pyedb/configuration/cfg_ports_sources.py +56 -23
  9. pyedb/configuration/configuration.py +18 -1
  10. pyedb/dotnet/{application → database}/Variables.py +21 -21
  11. pyedb/dotnet/{edb_core → database}/cell/connectable.py +5 -5
  12. pyedb/dotnet/{edb_core → database}/cell/hierarchy/component.py +11 -11
  13. pyedb/dotnet/{edb_core → database}/cell/hierarchy/hierarchy_obj.py +1 -1
  14. pyedb/dotnet/{edb_core → database}/cell/hierarchy/model.py +1 -1
  15. pyedb/dotnet/{edb_core → database}/cell/layout.py +17 -17
  16. pyedb/dotnet/{edb_core → database}/cell/layout_obj.py +3 -3
  17. pyedb/dotnet/{edb_core → database}/cell/primitive/bondwire.py +1 -1
  18. pyedb/dotnet/{edb_core → database}/cell/primitive/path.py +4 -4
  19. pyedb/dotnet/{edb_core → database}/cell/primitive/primitive.py +14 -14
  20. pyedb/dotnet/{edb_core → database}/cell/terminal/bundle_terminal.py +2 -2
  21. pyedb/dotnet/{edb_core → database}/cell/terminal/edge_terminal.py +4 -4
  22. pyedb/dotnet/{edb_core → database}/cell/terminal/padstack_instance_terminal.py +2 -2
  23. pyedb/dotnet/{edb_core → database}/cell/terminal/pingroup_terminal.py +2 -2
  24. pyedb/dotnet/{edb_core → database}/cell/terminal/point_terminal.py +2 -2
  25. pyedb/dotnet/{edb_core → database}/cell/terminal/terminal.py +11 -11
  26. pyedb/dotnet/{edb_core → database}/cell/voltage_regulator.py +2 -2
  27. pyedb/dotnet/{edb_core → database}/components.py +101 -124
  28. pyedb/dotnet/{edb_core → database}/definition/component_def.py +5 -5
  29. pyedb/dotnet/{edb_core → database}/definition/component_model.py +1 -1
  30. pyedb/dotnet/{edb_core → database}/definition/definition_obj.py +1 -1
  31. pyedb/dotnet/{edb_core → database}/definition/definitions.py +2 -2
  32. pyedb/dotnet/{edb_core → database}/definition/package_def.py +4 -4
  33. pyedb/dotnet/{edb_core → database}/dotnet/database.py +8 -8
  34. pyedb/dotnet/{edb_core → database}/dotnet/primitive.py +9 -9
  35. pyedb/dotnet/{edb_core → database}/edb_data/control_file.py +12 -12
  36. pyedb/dotnet/{edb_core → database}/edb_data/hfss_extent_info.py +7 -7
  37. pyedb/dotnet/{edb_core → database}/edb_data/nets_data.py +10 -13
  38. pyedb/dotnet/{edb_core → database}/edb_data/padstacks_data.py +16 -16
  39. pyedb/dotnet/{edb_core → database}/edb_data/ports.py +4 -4
  40. pyedb/dotnet/{edb_core → database}/edb_data/primitives_data.py +5 -5
  41. pyedb/dotnet/{edb_core → database}/edb_data/raptor_x_simulation_setup_data.py +4 -4
  42. pyedb/dotnet/{edb_core → database}/edb_data/simulation_configuration.py +10 -10
  43. pyedb/dotnet/{edb_core → database}/edb_data/sources.py +4 -4
  44. pyedb/dotnet/{edb_core → database}/edb_data/variables.py +1 -1
  45. pyedb/dotnet/{edb_core → database}/geometry/polygon_data.py +4 -4
  46. pyedb/dotnet/{edb_core → database}/hfss.py +8 -8
  47. pyedb/dotnet/{edb_core → database}/layout_obj_instance.py +1 -1
  48. pyedb/dotnet/{edb_core → database}/layout_validation.py +2 -2
  49. pyedb/dotnet/{edb_core → database}/materials.py +23 -8
  50. pyedb/dotnet/{edb_core → database}/modeler.py +27 -27
  51. pyedb/dotnet/{edb_core → database}/net_class.py +8 -8
  52. pyedb/dotnet/{edb_core → database}/nets.py +12 -12
  53. pyedb/dotnet/{edb_core → database}/padstack.py +15 -15
  54. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/mesh_operation.py +1 -1
  55. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/settings.py +3 -3
  56. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sim_setup_info.py +2 -2
  57. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/simulation_settings.py +1 -1
  58. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/siw_dc_ir_settings.py +1 -1
  59. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sweep_data.py +1 -1
  60. pyedb/dotnet/{edb_core → database}/siwave.py +10 -10
  61. pyedb/dotnet/{edb_core → database}/stackup.py +12 -12
  62. pyedb/dotnet/{edb_core → database}/utilities/hfss_simulation_setup.py +15 -15
  63. pyedb/dotnet/{edb_core → database}/utilities/obj_base.py +1 -1
  64. pyedb/dotnet/{edb_core → database}/utilities/simulation_setup.py +3 -3
  65. pyedb/dotnet/{edb_core → database}/utilities/siwave_simulation_setup.py +6 -6
  66. pyedb/dotnet/edb.py +117 -112
  67. pyedb/generic/design_types.py +26 -19
  68. pyedb/generic/general_methods.py +1 -1
  69. pyedb/generic/plot.py +0 -2
  70. pyedb/grpc/database/__init__.py +1 -0
  71. pyedb/grpc/database/components.py +2354 -0
  72. pyedb/grpc/database/control_file.py +1277 -0
  73. pyedb/grpc/database/definition/component_def.py +218 -0
  74. pyedb/grpc/database/definition/component_model.py +39 -0
  75. pyedb/grpc/database/definition/component_pin.py +32 -0
  76. pyedb/grpc/database/definition/materials.py +1207 -0
  77. pyedb/grpc/database/definition/n_port_component_model.py +34 -0
  78. pyedb/grpc/database/definition/package_def.py +227 -0
  79. pyedb/grpc/database/definition/padstack_def.py +842 -0
  80. pyedb/grpc/database/definitions.py +70 -0
  81. pyedb/grpc/database/general.py +43 -0
  82. pyedb/grpc/database/geometry/__init__.py +0 -0
  83. pyedb/grpc/database/geometry/arc_data.py +93 -0
  84. pyedb/grpc/database/geometry/point_3d_data.py +79 -0
  85. pyedb/grpc/database/geometry/point_data.py +30 -0
  86. pyedb/grpc/database/geometry/polygon_data.py +133 -0
  87. pyedb/grpc/database/hfss.py +1279 -0
  88. pyedb/grpc/database/hierarchy/__init__.py +0 -0
  89. pyedb/grpc/database/hierarchy/component.py +1301 -0
  90. pyedb/grpc/database/hierarchy/model.py +31 -0
  91. pyedb/grpc/database/hierarchy/netlist_model.py +30 -0
  92. pyedb/grpc/database/hierarchy/pin_pair_model.py +128 -0
  93. pyedb/grpc/database/hierarchy/pingroup.py +245 -0
  94. pyedb/grpc/database/hierarchy/s_parameter_model.py +33 -0
  95. pyedb/grpc/database/hierarchy/spice_model.py +48 -0
  96. pyedb/grpc/database/layers/__init__.py +0 -0
  97. pyedb/grpc/database/layers/layer.py +57 -0
  98. pyedb/grpc/database/layers/stackup_layer.py +410 -0
  99. pyedb/grpc/database/layout/__init__.py +0 -0
  100. pyedb/grpc/database/layout/cell.py +30 -0
  101. pyedb/grpc/database/layout/layout.py +196 -0
  102. pyedb/grpc/database/layout/voltage_regulator.py +149 -0
  103. pyedb/grpc/database/layout_validation.py +319 -0
  104. pyedb/grpc/database/modeler.py +1468 -0
  105. pyedb/grpc/database/net/__init__.py +0 -0
  106. pyedb/grpc/database/net/differential_pair.py +138 -0
  107. pyedb/grpc/database/net/extended_net.py +340 -0
  108. pyedb/grpc/database/net/net.py +198 -0
  109. pyedb/grpc/database/net/net_class.py +93 -0
  110. pyedb/grpc/database/nets.py +633 -0
  111. pyedb/grpc/database/padstacks.py +1500 -0
  112. pyedb/grpc/database/ports/__init__.py +0 -0
  113. pyedb/grpc/database/ports/ports.py +396 -0
  114. pyedb/grpc/database/primitive/__init__.py +3 -0
  115. pyedb/grpc/database/primitive/bondwire.py +181 -0
  116. pyedb/grpc/database/primitive/circle.py +75 -0
  117. pyedb/grpc/database/primitive/padstack_instance.py +1116 -0
  118. pyedb/grpc/database/primitive/path.py +346 -0
  119. pyedb/grpc/database/primitive/polygon.py +276 -0
  120. pyedb/grpc/database/primitive/primitive.py +739 -0
  121. pyedb/grpc/database/primitive/rectangle.py +146 -0
  122. pyedb/grpc/database/simulation_setup/__init__.py +0 -0
  123. pyedb/grpc/database/simulation_setup/adaptive_frequency.py +33 -0
  124. pyedb/grpc/database/simulation_setup/hfss_advanced_meshing_settings.py +32 -0
  125. pyedb/grpc/database/simulation_setup/hfss_advanced_settings.py +59 -0
  126. pyedb/grpc/database/simulation_setup/hfss_dcr_settings.py +35 -0
  127. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +61 -0
  128. pyedb/grpc/database/simulation_setup/hfss_settings_options.py +78 -0
  129. pyedb/grpc/database/simulation_setup/hfss_simulation_settings.py +118 -0
  130. pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +355 -0
  131. pyedb/grpc/database/simulation_setup/hfss_solver_settings.py +34 -0
  132. pyedb/grpc/database/simulation_setup/mesh_operation.py +34 -0
  133. pyedb/grpc/database/simulation_setup/raptor_x_advanced_settings.py +34 -0
  134. pyedb/grpc/database/simulation_setup/raptor_x_general_settings.py +33 -0
  135. pyedb/grpc/database/simulation_setup/raptor_x_simulation_settings.py +64 -0
  136. pyedb/grpc/database/simulation_setup/raptor_x_simulation_setup.py +125 -0
  137. pyedb/grpc/database/simulation_setup/siwave_dcir_simulation_setup.py +34 -0
  138. pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +119 -0
  139. pyedb/grpc/database/simulation_setup/sweep_data.py +32 -0
  140. pyedb/grpc/database/siwave.py +1023 -0
  141. pyedb/grpc/database/source_excitations.py +2572 -0
  142. pyedb/grpc/database/stackup.py +2574 -0
  143. pyedb/grpc/database/terminal/__init__.py +0 -0
  144. pyedb/grpc/database/terminal/bundle_terminal.py +218 -0
  145. pyedb/grpc/database/terminal/edge_terminal.py +51 -0
  146. pyedb/grpc/database/terminal/padstack_instance_terminal.py +171 -0
  147. pyedb/grpc/database/terminal/pingroup_terminal.py +162 -0
  148. pyedb/grpc/database/terminal/point_terminal.py +99 -0
  149. pyedb/grpc/database/terminal/terminal.py +470 -0
  150. pyedb/grpc/database/utility/__init__.py +3 -0
  151. pyedb/grpc/database/utility/constants.py +25 -0
  152. pyedb/grpc/database/utility/heat_sink.py +124 -0
  153. pyedb/grpc/database/utility/hfss_extent_info.py +448 -0
  154. pyedb/grpc/database/utility/layout_statistics.py +277 -0
  155. pyedb/grpc/database/utility/rlc.py +80 -0
  156. pyedb/grpc/database/utility/simulation_configuration.py +3305 -0
  157. pyedb/grpc/database/utility/sources.py +388 -0
  158. pyedb/grpc/database/utility/sweep_data_distribution.py +83 -0
  159. pyedb/grpc/database/utility/xml_control_file.py +1277 -0
  160. pyedb/grpc/edb.py +4151 -0
  161. pyedb/grpc/edb_init.py +481 -0
  162. pyedb/grpc/rpc_session.py +177 -0
  163. pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +3 -2
  164. pyedb/ipc2581/ecad/cad_data/feature.py +4 -3
  165. pyedb/ipc2581/ecad/cad_data/layer_feature.py +32 -20
  166. pyedb/ipc2581/ecad/cad_data/outline.py +3 -2
  167. pyedb/ipc2581/ecad/cad_data/package.py +4 -3
  168. pyedb/ipc2581/ecad/cad_data/path.py +82 -31
  169. pyedb/ipc2581/ecad/cad_data/polygon.py +122 -60
  170. pyedb/ipc2581/ecad/cad_data/profile.py +13 -12
  171. pyedb/ipc2581/ecad/cad_data/step.py +53 -21
  172. pyedb/ipc2581/ipc2581.py +47 -49
  173. pyedb/modeler/geometry_operators.py +1 -1
  174. {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/METADATA +5 -2
  175. pyedb-0.39.0.dist-info/RECORD +288 -0
  176. pyedb-0.38.0.dist-info/RECORD +0 -195
  177. /pyedb/dotnet/{edb_core → database}/__init__.py +0 -0
  178. /pyedb/dotnet/{application → database/cell}/__init__.py +0 -0
  179. /pyedb/dotnet/{edb_core/cell → database/cell/hierarchy}/__init__.py +0 -0
  180. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/netlist_model.py +0 -0
  181. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/pin_pair_model.py +0 -0
  182. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/s_parameter_model.py +0 -0
  183. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/spice_model.py +0 -0
  184. /pyedb/dotnet/{edb_core → database}/cell/primitive/__init__.py +0 -0
  185. /pyedb/dotnet/{edb_core/cell/hierarchy → database/cell/terminal}/__init__.py +0 -0
  186. /pyedb/dotnet/{edb_core/cell/terminal → database/definition}/__init__.py +0 -0
  187. /pyedb/dotnet/{edb_core/definition → database/dotnet}/__init__.py +0 -0
  188. /pyedb/dotnet/{edb_core/dotnet → database/edb_data}/__init__.py +0 -0
  189. /pyedb/dotnet/{edb_core → database}/edb_data/design_options.py +0 -0
  190. /pyedb/dotnet/{edb_core → database}/edb_data/edbvalue.py +0 -0
  191. /pyedb/dotnet/{edb_core → database}/edb_data/layer_data.py +0 -0
  192. /pyedb/dotnet/{edb_core → database}/edb_data/utilities.py +0 -0
  193. /pyedb/dotnet/{edb_core → database}/general.py +0 -0
  194. /pyedb/dotnet/{edb_core/edb_data → database/geometry}/__init__.py +0 -0
  195. /pyedb/dotnet/{edb_core → database}/geometry/point_data.py +0 -0
  196. /pyedb/dotnet/{edb_core → database}/sim_setup_data/__init__.py +0 -0
  197. /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/__init__.py +0 -0
  198. /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/adaptive_frequency_data.py +0 -0
  199. /pyedb/dotnet/{edb_core/geometry → database/sim_setup_data/io}/__init__.py +0 -0
  200. /pyedb/dotnet/{edb_core → database}/sim_setup_data/io/siwave.py +0 -0
  201. /pyedb/dotnet/{edb_core → database}/utilities/__init__.py +0 -0
  202. /pyedb/dotnet/{edb_core → database}/utilities/heatsink.py +0 -0
  203. /pyedb/{dotnet/edb_core/sim_setup_data/io → grpc/database/definition}/__init__.py +0 -0
  204. {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/LICENSE +0 -0
  205. {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,842 @@
1
+ # Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
2
+ # SPDX-License-Identifier: MIT
3
+ #
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ import math
24
+
25
+ from ansys.edb.core.definition.padstack_def import PadstackDef as GrpcPadstackDef
26
+ from ansys.edb.core.definition.padstack_def_data import (
27
+ PadGeometryType as GrpcPadGeometryType,
28
+ )
29
+ from ansys.edb.core.definition.padstack_def_data import (
30
+ PadstackHoleRange as GrpcPadstackHoleRange,
31
+ )
32
+ from ansys.edb.core.definition.padstack_def_data import PadType as GrpcPadType
33
+ import ansys.edb.core.geometry.polygon_data
34
+ from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
35
+ from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure
36
+ from ansys.edb.core.hierarchy.structure3d import Structure3D as GrpcStructure3D
37
+ from ansys.edb.core.primitive.primitive import Circle as GrpcCircle
38
+ from ansys.edb.core.utility.value import Value as GrpcValue
39
+
40
+ from pyedb.generic.general_methods import generate_unique_name
41
+
42
+
43
+ class PadProperties:
44
+ """Manages EDB functionalities for pad properties.
45
+
46
+ Parameters
47
+ ----------
48
+ edb_padstack :
49
+
50
+ layer_name : str
51
+ Name of the layer.
52
+ pad_type :
53
+ Type of the pad.
54
+ pedbpadstack : str
55
+ Inherited AEDT object.
56
+
57
+ Examples
58
+ --------
59
+ >>> from pyedb import Edb
60
+ >>> edb = Edb(myedb, edbversion="2021.2")
61
+ >>> edb_pad_properties = edb.padstacks.definitions["MyPad"].pad_by_layer["TOP"]
62
+ """
63
+
64
+ def __init__(self, edb_padstack, layer_name, pad_type, p_edb_padstack):
65
+ self._edb_object = edb_padstack
66
+ self._pedbpadstack = p_edb_padstack
67
+ self.layer_name = layer_name
68
+ self.pad_type = pad_type
69
+ self._edb_padstack = self._edb_object
70
+
71
+ @property
72
+ def _stackup_layers(self):
73
+ return self._pedbpadstack._stackup_layers
74
+
75
+ @property
76
+ def _edb(self):
77
+ return self._pedbpadstack._edb
78
+
79
+ @property
80
+ def _pad_parameter_value(self):
81
+ p_val = self._edb_padstack.get_pad_parameters(self.layer_name, GrpcPadType.REGULAR_PAD)
82
+ if isinstance(p_val[0], ansys.edb.core.geometry.polygon_data.PolygonData):
83
+ p_val = [GrpcPadGeometryType.PADGEOMTYPE_POLYGON] + [i for i in p_val]
84
+ return p_val
85
+
86
+ @property
87
+ def geometry_type(self):
88
+ """Geometry type.
89
+
90
+ Returns
91
+ -------
92
+ int
93
+ Type of the geometry.
94
+ """
95
+ return self._pad_parameter_value[0].value
96
+
97
+ @property
98
+ def _edb_geometry_type(self):
99
+ return self._pad_parameter_value[0]
100
+
101
+ @property
102
+ def shape(self):
103
+ """Pad shape.
104
+
105
+ Returns
106
+ -------
107
+ str
108
+ pad shape.
109
+ """
110
+ return self._pad_parameter_value[0].name.split("_")[-1].lower()
111
+
112
+ @property
113
+ def parameters_values(self):
114
+ """Parameters.
115
+
116
+ Returns
117
+ -------
118
+ list
119
+ List of parameters.
120
+ """
121
+ try:
122
+ return [i.value for i in self._pad_parameter_value[1]]
123
+ except TypeError:
124
+ return []
125
+
126
+ @property
127
+ def parameters_values_string(self):
128
+ """Parameters value in string format."""
129
+ try:
130
+ return [str(i) for i in self._pad_parameter_value[1]]
131
+ except TypeError:
132
+ return []
133
+
134
+ @property
135
+ def polygon_data(self):
136
+ """Parameters.
137
+
138
+ Returns
139
+ -------
140
+ list
141
+ List of parameters.
142
+ """
143
+ p = self._pad_parameter_value[1]
144
+ return p if isinstance(p, ansys.edb.core.geometry.polygon_data.PolygonData) else None
145
+
146
+ @property
147
+ def offset_x(self):
148
+ """Offset for the X axis.
149
+
150
+ Returns
151
+ -------
152
+ str
153
+ Offset for the X axis.
154
+ """
155
+ return self._pad_parameter_value[2].value
156
+
157
+ @property
158
+ def offset_y(self):
159
+ """Offset for the Y axis.
160
+
161
+ Returns
162
+ -------
163
+ str
164
+ Offset for the Y axis.
165
+ """
166
+
167
+ return self._pad_parameter_value[3].value
168
+
169
+ @offset_x.setter
170
+ def offset_x(self, value):
171
+ self._update_pad_parameters_parameters(offsetx=value)
172
+
173
+ @offset_y.setter
174
+ def offset_y(self, value):
175
+ self._update_pad_parameters_parameters(offsety=value)
176
+
177
+ @property
178
+ def rotation(self):
179
+ """Rotation.
180
+
181
+ Returns
182
+ -------
183
+ str
184
+ Value for the rotation.
185
+ """
186
+
187
+ return self._pad_parameter_value[4].value
188
+
189
+ @rotation.setter
190
+ def rotation(self, value):
191
+ self._update_pad_parameters_parameters(rotation=value)
192
+
193
+ @rotation.setter
194
+ def rotation(self, value):
195
+ self._update_pad_parameters_parameters(rotation=value)
196
+
197
+ @parameters_values.setter
198
+ def parameters_values(self, value):
199
+ if isinstance(value, (float, str)):
200
+ value = [value]
201
+ self._update_pad_parameters_parameters(params=value)
202
+
203
+ def _update_pad_parameters_parameters(
204
+ self,
205
+ layer_name=None,
206
+ pad_type=None,
207
+ geom_type=None,
208
+ params=None,
209
+ offsetx=None,
210
+ offsety=None,
211
+ rotation=None,
212
+ ):
213
+ if layer_name is None:
214
+ layer_name = self.layer_name
215
+ if pad_type is None:
216
+ pad_type = GrpcPadType.REGULAR_PAD
217
+ if geom_type is None:
218
+ geom_type = self.geometry_type
219
+ for k in GrpcPadGeometryType:
220
+ if k.value == geom_type:
221
+ geom_type = k
222
+ if params is None:
223
+ params = self._pad_parameter_value[1]
224
+ elif isinstance(params, list):
225
+ offsetx = [GrpcValue(i, self._pedbpadstack._pedb.db) for i in params]
226
+ if rotation is None:
227
+ rotation = self._pad_parameter_value[4]
228
+ elif isinstance(rotation, (str, float, int)):
229
+ rotation = GrpcValue(rotation, self._pedbpadstack._pedb.db)
230
+ if offsetx is None:
231
+ offsetx = self._pad_parameter_value[2]
232
+ elif isinstance(offsetx, (str, float, int)):
233
+ offsetx = GrpcValue(offsetx, self._pedbpadstack._pedb.db)
234
+ if offsety is None:
235
+ offsety = self._pad_parameter_value[3]
236
+ elif isinstance(offsety, (str, float, int)):
237
+ offsety = GrpcValue(offsety, self._pedbpadstack._pedb.db)
238
+ self._edb_padstack.set_pad_parameters(
239
+ layer=layer_name,
240
+ pad_type=pad_type,
241
+ type_geom=geom_type,
242
+ offset_x=GrpcValue(offsetx, self._pedbpadstack._pedb.db),
243
+ offset_y=GrpcValue(offsety, self._pedbpadstack._pedb.db),
244
+ rotation=GrpcValue(rotation, self._pedbpadstack._pedb.db),
245
+ sizes=[GrpcValue(i, self._pedbpadstack._pedb.db) for i in params],
246
+ )
247
+
248
+
249
+ class PadstackDef(GrpcPadstackDef):
250
+ """Manages EDB functionalities for a padstack.
251
+
252
+ Parameters
253
+ ----------
254
+ edb_padstack :
255
+
256
+ ppadstack : str
257
+ Inherited AEDT object.
258
+
259
+ Examples
260
+ --------
261
+ >>> from pyedb import Edb
262
+ >>> edb = Edb(myedb, edbversion="2021.2")
263
+ >>> edb_padstack = edb.padstacks.definitions["MyPad"]
264
+ """
265
+
266
+ def __init__(self, pedb, edb_object):
267
+ super().__init__(edb_object.msg)
268
+ self._pedb = pedb
269
+ self._pad_by_layer = {}
270
+ self._antipad_by_layer = {}
271
+ self._thermalpad_by_layer = {}
272
+ self._bounding_box = []
273
+
274
+ @property
275
+ def instances(self):
276
+ """Definitions Instances.
277
+
278
+ Returns
279
+ -------
280
+ List[:class:`PadstackInstance <pyedb.grpc.database.primitive.padstack_instance.PadstackInstance>`]
281
+ List of PadstackInstance objects.
282
+ """
283
+ return [i for i in list(self._pedb.padstacks.instances.values()) if i.padstack_def.name == self.name]
284
+
285
+ @property
286
+ def layers(self):
287
+ """Layers.
288
+
289
+ Returns
290
+ -------
291
+ list[str]
292
+ List of layer names.
293
+ """
294
+ return self.data.layer_names
295
+
296
+ @property
297
+ def start_layer(self):
298
+ """Starting layer.
299
+
300
+ Returns
301
+ -------
302
+ str
303
+ Name of the starting layer.
304
+ """
305
+ return self.layers[0]
306
+
307
+ @property
308
+ def stop_layer(self):
309
+ """Stopping layer.
310
+
311
+ Returns
312
+ -------
313
+ str
314
+ Name of the stopping layer.
315
+ """
316
+ return self.layers[-1]
317
+
318
+ @property
319
+ def hole_diameter(self):
320
+ """Hole diameter.
321
+
322
+ Returns
323
+ -------
324
+ float
325
+ Diameter value.
326
+
327
+ """
328
+ try:
329
+ hole_parameter = self.data.get_hole_parameters()
330
+ if hole_parameter[0].name.lower() == "padgeomtype_circle":
331
+ return round(hole_parameter[1][0].value, 6)
332
+ except:
333
+ return 0.0
334
+
335
+ @hole_diameter.setter
336
+ def hole_diameter(self, value):
337
+ hole_parameter = self.data.get_hole_parameters()
338
+ if not isinstance(value, list):
339
+ value = [GrpcValue(value)]
340
+ else:
341
+ value = [GrpcValue(p) for p in value]
342
+ hole_size = value
343
+ geometry_type = hole_parameter[0]
344
+ hole_offset_x = hole_parameter[2]
345
+ hole_offset_y = hole_parameter[3]
346
+ if not isinstance(geometry_type, GrpcPolygonData):
347
+ hole_rotation = hole_parameter[4]
348
+ self.data.set_hole_parameters(
349
+ offset_x=hole_offset_x,
350
+ offset_y=hole_offset_y,
351
+ rotation=hole_rotation,
352
+ type_geom=geometry_type,
353
+ sizes=hole_size,
354
+ )
355
+
356
+ @property
357
+ def hole_type(self):
358
+ """Holy type.
359
+
360
+ Returns
361
+ -------
362
+ float
363
+ hole type.
364
+
365
+ """
366
+ return self.data.get_hole_parameters()[0].value
367
+
368
+ @property
369
+ def edb_hole_type(self):
370
+ """EDB hole type.
371
+
372
+ Returns
373
+ -------
374
+ str
375
+ Hole type.
376
+
377
+ """
378
+ return self.data.get_hole_parameters()[0]
379
+
380
+ @property
381
+ def hole_offset_x(self):
382
+ """Hole offset for the X axis.
383
+
384
+ Returns
385
+ -------
386
+ float
387
+ Hole offset value for the X axis.
388
+ """
389
+ try:
390
+ return round(self.data.get_hole_parameters()[2].value, 6)
391
+ except:
392
+ return 0.0
393
+
394
+ @hole_offset_x.setter
395
+ def hole_offset_x(self, value):
396
+ hole_parameter = list(self.data.get_hole_parameters())
397
+ hole_parameter[2] = GrpcValue(value, self._pedb.db)
398
+ self.data.set_hole_parameters(
399
+ offset_x=hole_parameter[2],
400
+ offset_y=hole_parameter[3],
401
+ rotation=hole_parameter[4],
402
+ type_geom=hole_parameter[0],
403
+ sizes=hole_parameter[1],
404
+ )
405
+
406
+ @property
407
+ def hole_offset_y(self):
408
+ """Hole offset for the Y axis.
409
+
410
+ Returns
411
+ -------
412
+ float
413
+ Hole offset value for the Y axis.
414
+ """
415
+ try:
416
+ return round(self.data.get_hole_parameters()[3].value, 6)
417
+ except:
418
+ return 0.0
419
+
420
+ @hole_offset_y.setter
421
+ def hole_offset_y(self, value):
422
+ hole_parameter = list(self.data.get_hole_parameters())
423
+ hole_parameter[3] = GrpcValue(value, self._pedb.db)
424
+ self.data.set_hole_parameters(
425
+ offset_x=hole_parameter[2],
426
+ offset_y=hole_parameter[3],
427
+ rotation=hole_parameter[4],
428
+ type_geom=hole_parameter[0],
429
+ sizes=hole_parameter[1],
430
+ )
431
+
432
+ @property
433
+ def hole_rotation(self):
434
+ """Hole rotation.
435
+
436
+ Returns
437
+ -------
438
+ float
439
+ Value for the hole rotation.
440
+ """
441
+ try:
442
+ return round(self.data.get_hole_parameters()[4].value, 6)
443
+ except:
444
+ return 0.0
445
+
446
+ @hole_rotation.setter
447
+ def hole_rotation(self, value):
448
+ hole_parameter = list(self.data.get_hole_parameters())
449
+ hole_parameter[4] = GrpcValue(value, self._pedb.db)
450
+ self.data.set_hole_parameters(
451
+ offset_x=hole_parameter[2],
452
+ offset_y=hole_parameter[3],
453
+ rotation=hole_parameter[4],
454
+ type_geom=hole_parameter[0],
455
+ sizes=hole_parameter[1],
456
+ )
457
+
458
+ @property
459
+ def pad_by_layer(self):
460
+ """Pad by layer.
461
+
462
+ Returns
463
+ -------
464
+ Dict[str, :class:`PadProperties <pyedb.grpc.database.definition.padstack_def.PadProperties>`]
465
+ Dictionary with layer as key and PadProperties as value.
466
+ """
467
+ if not self._pad_by_layer:
468
+ for layer in self.layers:
469
+ try:
470
+ self._pad_by_layer[layer] = PadProperties(self.data, layer, GrpcPadType.REGULAR_PAD, self)
471
+ except:
472
+ self._pad_by_layer[layer] = None
473
+ return self._pad_by_layer
474
+
475
+ @property
476
+ def antipad_by_layer(self):
477
+ """Antipad by layer.
478
+
479
+ Returns
480
+ -------
481
+ Dict[str, :class:`PadProperties <pyedb.grpc.database.definition.padstack_def.PadProperties>`]
482
+ Dictionary with layer as key and PadProperties as value.
483
+ """
484
+ if not self._antipad_by_layer:
485
+ for layer in self.layers:
486
+ try:
487
+ self._pad_by_layer[layer] = PadProperties(self.data, layer, GrpcPadType.ANTI_PAD, self)
488
+ except:
489
+ self._antipad_by_layer[layer] = None
490
+ return self._antipad_by_layer
491
+
492
+ @property
493
+ def thermalpad_by_layer(self):
494
+ """Thermal by layer.
495
+
496
+ Returns
497
+ -------
498
+ Dict[str, :class:`PadProperties <pyedb.grpc.database.definition.padstack_def.PadProperties>`]
499
+ Dictionary with layer as key and PadProperties as value.
500
+ """
501
+ if not self._thermalpad_by_layer:
502
+ for layer in self.layers:
503
+ try:
504
+ self._pad_by_layer[layer] = PadProperties(self.data, layer, GrpcPadType.THERMAL_PAD, self)
505
+ except:
506
+ self._thermalpad_by_layer[layer] = None
507
+ return self._thermalpad_by_layer
508
+
509
+ @property
510
+ def hole_plating_ratio(self):
511
+ """Hole plating ratio.
512
+
513
+ Returns
514
+ -------
515
+ float
516
+ Percentage for the hole plating.
517
+ """
518
+ return round(self.data.plating_percentage.value, 6)
519
+
520
+ @hole_plating_ratio.setter
521
+ def hole_plating_ratio(self, ratio):
522
+ self.data.plating_percentage = GrpcValue(ratio)
523
+
524
+ @property
525
+ def hole_plating_thickness(self):
526
+ """Hole plating thickness.
527
+
528
+ Returns
529
+ -------
530
+ float
531
+ Thickness of the hole plating if present.
532
+ """
533
+ try:
534
+ if len(self.data.get_hole_parameters()) > 0:
535
+ return round((self.hole_diameter * self.hole_plating_ratio / 100) / 2, 6)
536
+ else:
537
+ return 0.0
538
+ except:
539
+ return 0.0
540
+
541
+ @hole_plating_thickness.setter
542
+ def hole_plating_thickness(self, value):
543
+ """Hole plating thickness.
544
+
545
+ Returns
546
+ -------
547
+ float
548
+ Thickness of the hole plating if present.
549
+ """
550
+ hr = 200 * GrpcValue(value).value / self.hole_diameter
551
+ self.hole_plating_ratio = hr
552
+
553
+ @property
554
+ def hole_finished_size(self):
555
+ """Finished hole size.
556
+
557
+ Returns
558
+ -------
559
+ float
560
+ Finished size of the hole (Total Size + PlatingThickess*2).
561
+ """
562
+ try:
563
+ if len(self.data.get_hole_parameters()) > 0:
564
+ return round(self.hole_diameter - (self.hole_plating_thickness * 2), 6)
565
+ else:
566
+ return 0.0
567
+ except:
568
+ return 0.0
569
+
570
+ @property
571
+ def hole_range(self):
572
+ """Get hole range value from padstack definition.
573
+
574
+ Returns
575
+ -------
576
+ str
577
+ Possible returned values are ``"through"``, ``"begin_on_upper_pad"``,
578
+ ``"end_on_lower_pad"``, ``"upper_pad_to_lower_pad"``, and ``"undefined"``.
579
+ """
580
+ return self.data.hole_range.name.lower()
581
+
582
+ @hole_range.setter
583
+ def hole_range(self, value):
584
+ if isinstance(value, str):
585
+ if value == "through":
586
+ self.data.hole_range = GrpcPadstackHoleRange.THROUGH
587
+ elif value == "begin_on_upper_pad":
588
+ self.data.hole_range = GrpcPadstackHoleRange.BEGIN_ON_UPPER_PAD
589
+ elif value == "end_on_lower_pad":
590
+ self.data.hole_range = GrpcPadstackHoleRange.END_ON_LOWER_PAD
591
+ elif value == "upper_pad_to_lower_pad":
592
+ self.data.hole_range = GrpcPadstackHoleRange.UPPER_PAD_TO_LOWER_PAD
593
+ else: # pragma no cover
594
+ self.data.hole_range = GrpcPadstackHoleRange.UNKNOWN_RANGE
595
+
596
+ @property
597
+ def material(self):
598
+ """Return hole material name."""
599
+ return self.data.material.value
600
+
601
+ @material.setter
602
+ def material(self, value):
603
+ self.data.material.value = value
604
+
605
+ def convert_to_3d_microvias(self, convert_only_signal_vias=True, hole_wall_angle=15, delete_padstack_def=True):
606
+ """Convert actual padstack instance to microvias 3D Objects with a given aspect ratio.
607
+
608
+ Parameters
609
+ ----------
610
+ convert_only_signal_vias : bool, optional
611
+ Either to convert only vias belonging to signal nets or all vias. Defaults is ``True``.
612
+ hole_wall_angle : float, optional
613
+ Angle of laser penetration in degrees. The angle defines the lowest hole diameter with this formula:
614
+ HoleDiameter -2*tan(laser_angle* Hole depth). Hole depth is the height of the via (dielectric thickness).
615
+ The default is ``15``.
616
+ The lowest hole is ``0.75*HoleDepth/HoleDiam``.
617
+ delete_padstack_def : bool, optional
618
+ Whether to delete the padstack definition. The default is ``True``.
619
+ If ``False``, the padstack definition is not deleted and the hole size is set to zero.
620
+
621
+ Returns
622
+ -------
623
+ ``True`` when successful, ``False`` when failed.
624
+ """
625
+
626
+ if isinstance(self.data.get_hole_parameters()[0], GrpcPolygonData):
627
+ self._pedb.logger.error("Microvias cannot be applied on vias using hole shape polygon")
628
+ return False
629
+
630
+ if self.start_layer == self.stop_layer:
631
+ self._pedb.logger.error("Microvias cannot be applied when Start and Stop Layers are the same.")
632
+ layout = self._pedb.active_layout
633
+ layers = self._pedb.stackup.signal_layers
634
+ layer_names = [i for i in list(layers.keys())]
635
+ if convert_only_signal_vias:
636
+ signal_nets = [i for i in list(self._pedb._pedb.nets.signal_nets.keys())]
637
+ topl, topz, bottoml, bottomz = self._pedb.stackup.limits(True)
638
+ if self.start_layer in layers:
639
+ start_elevation = layers[self.start_layer].lower_elevation
640
+ else:
641
+ start_elevation = layers[self.instances[0].start_layer].lower_elevation
642
+ if self.stop_layer in layers:
643
+ stop_elevation = layers[self.stop_layer].upper_elevation
644
+ else:
645
+ stop_elevation = layers[self.instances[0].stop_layer].upper_elevation
646
+
647
+ diel_thick = abs(start_elevation - stop_elevation)
648
+ if self.hole_diameter:
649
+ rad1 = self.hole_diameter / 2 - math.tan(hole_wall_angle * diel_thick * math.pi / 180)
650
+ rad2 = self.hole_diameter / 2
651
+ else:
652
+ rad1 = 0.0
653
+ rad2 = 0.0
654
+
655
+ if start_elevation < (topz + bottomz) / 2:
656
+ rad1, rad2 = rad2, rad1
657
+ i = 0
658
+ for via in self.instances:
659
+ if convert_only_signal_vias and via.net_name in signal_nets or not convert_only_signal_vias:
660
+ pos = via.position
661
+ started = False
662
+ if len(self.pad_by_layer[self.start_layer].parameters_values) == 0:
663
+ self._pedb.modeler.create_polygon(
664
+ self.pad_by_layer[self.start_layer].polygon_data,
665
+ layer_name=self.start_layer,
666
+ net_name=via.net_name,
667
+ )
668
+ else:
669
+ GrpcCircle.create(
670
+ layout,
671
+ self.start_layer,
672
+ via.net,
673
+ GrpcValue(pos[0]),
674
+ GrpcValue(pos[1]),
675
+ GrpcValue(self.pad_by_layer[self.start_layer].parameters_values[0] / 2),
676
+ )
677
+ if len(self.pad_by_layer[self.stop_layer].parameters_values) == 0:
678
+ self._pedb.modeler.create_polygon(
679
+ self.pad_by_layer[self.stop_layer].polygon_data,
680
+ layer_name=self.stop_layer,
681
+ net_name=via.net_name,
682
+ )
683
+ else:
684
+ GrpcCircle.create(
685
+ layout,
686
+ self.stop_layer,
687
+ via.net,
688
+ GrpcValue(pos[0]),
689
+ GrpcValue(pos[1]),
690
+ GrpcValue(self.pad_by_layer[self.stop_layer].parameters_values[0] / 2),
691
+ )
692
+ for layer_name in layer_names:
693
+ stop = ""
694
+ if layer_name == via.start_layer or started:
695
+ start = layer_name
696
+ stop = layer_names[layer_names.index(layer_name) + 1]
697
+ cloned_circle = GrpcCircle.create(
698
+ layout,
699
+ start,
700
+ via.net,
701
+ GrpcValue(pos[0]),
702
+ GrpcValue(pos[1]),
703
+ GrpcValue(rad1),
704
+ )
705
+ cloned_circle2 = GrpcCircle.create(
706
+ layout,
707
+ stop,
708
+ via.net,
709
+ GrpcValue(pos[0]),
710
+ GrpcValue(pos[1]),
711
+ GrpcValue(rad2),
712
+ )
713
+ s3d = GrpcStructure3D.create(
714
+ layout, generate_unique_name("via3d_" + via.aedt_name.replace("via_", ""), n=3)
715
+ )
716
+ s3d.add_member(cloned_circle)
717
+ s3d.add_member(cloned_circle2)
718
+ if not self.data.material.value:
719
+ self._pedb.logger.warning(
720
+ f"Padstack definution {self.name} has no material defined." f"Defaulting to copper"
721
+ )
722
+ self.data.material = "copper"
723
+ s3d.set_material(self.data.material.value)
724
+ s3d.mesh_closure = GrpcMeshClosure.ENDS_CLOSED
725
+ started = True
726
+ i += 1
727
+ if stop == via.stop_layer:
728
+ break
729
+ if delete_padstack_def: # pragma no cover
730
+ via.delete()
731
+ else: # pragma no cover
732
+ self.hole_diameter = 0.0
733
+ self._pedb.logger.info("Padstack definition kept, hole size set to 0.")
734
+
735
+ self._pedb.logger.info(f"{i} Converted successfully to 3D Objects.")
736
+ return True
737
+
738
+ def split_to_microvias(self):
739
+ """Convert actual padstack definition to multiple microvias definitions.
740
+
741
+ Returns
742
+ -------
743
+ List[:class:`PadstackInstance <pyedb.grpc.database.primitive.padstack_instance.PadstackInstance>`]
744
+ """
745
+ from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
746
+
747
+ if self.start_layer == self.stop_layer:
748
+ self._pedb.logger.error("Microvias cannot be applied when Start and Stop Layers are the same.")
749
+ layout = self._pedb.active_layout
750
+ layers = self._pedb.stackup.signal_layers
751
+ layer_names = [i for i in list(layers.keys())]
752
+ if abs(layer_names.index(self.start_layer) - layer_names.index(self.stop_layer)) < 2:
753
+ self._pedb.logger.error(
754
+ "Conversion can be applied only if padstack definition is composed by more than 2 layers."
755
+ )
756
+ return False
757
+ started = False
758
+ new_instances = []
759
+ for layer_name in layer_names:
760
+ stop = ""
761
+ if layer_name == self.start_layer or started:
762
+ start = layer_name
763
+ stop = layer_names[layer_names.index(layer_name) + 1]
764
+ new_padstack_name = f"MV_{self.name}_{start}_{stop}"
765
+ included = [start, stop]
766
+ new_padstack_definition = GrpcPadstackDef.create(self._pedb.db, new_padstack_name)
767
+ new_padstack_definition.data.add_layers(included)
768
+ for layer in included:
769
+ pl = self.pad_by_layer[layer]
770
+ new_padstack_definition.data.set_pad_parameters(
771
+ layer=layer,
772
+ pad_type=GrpcPadType.REGULAR_PAD,
773
+ offset_x=GrpcValue(pl.offset_x, self._pedb.db),
774
+ offset_y=GrpcValue(pl.offset_y, self._pedb.db),
775
+ rotation=GrpcValue(pl.rotation, self._pedb.db),
776
+ type_geom=pl._edb_geometry_type,
777
+ sizes=pl.parameters_values,
778
+ )
779
+ antipads = self.antipad_by_layer
780
+ if layer in antipads:
781
+ pl = antipads[layer]
782
+ new_padstack_definition.data.set_pad_parameters(
783
+ layer=layer,
784
+ pad_type=GrpcPadType.ANTI_PAD,
785
+ offset_x=GrpcValue(pl.offset_x, self._pedb.db),
786
+ offset_y=GrpcValue(pl.offset_y, self._pedb.db),
787
+ rotation=GrpcValue(pl.rotation, self._pedb.db),
788
+ type_geom=pl._edb_geometry_type,
789
+ sizes=pl.parameters_values,
790
+ )
791
+ thermal_pads = self.thermalpad_by_layer
792
+ if layer in thermal_pads:
793
+ pl = thermal_pads[layer]
794
+ new_padstack_definition.data.set_pad_parameters(
795
+ layer=layer,
796
+ pad_type=GrpcPadType.THERMAL_PAD,
797
+ offset_x=GrpcValue(pl.offset_x, self._pedb.db),
798
+ offset_y=GrpcValue(pl.offset_y, self._pedb.db),
799
+ rotation=GrpcValue(pl.rotation, self._pedb.db),
800
+ type_geom=pl._edb_geometry_type,
801
+ sizes=pl.parameters_values,
802
+ )
803
+ new_padstack_definition.data.set_hole_parameters(
804
+ offset_x=GrpcValue(self.hole_offset_x, self._pedb.db),
805
+ offset_y=GrpcValue(self.hole_offset_y, self._pedb.db),
806
+ rotation=GrpcValue(self.hole_rotation, self._pedb.db),
807
+ type_geom=self.edb_hole_type,
808
+ sizes=[self.hole_diameter],
809
+ )
810
+ new_padstack_definition.data.material = self.material
811
+ new_padstack_definition.data.plating_percentage = GrpcValue(self.hole_plating_ratio, self._pedb.db)
812
+ new_instances.append(PadstackDef(self._pedb, new_padstack_definition))
813
+ started = True
814
+ if self.stop_layer == stop:
815
+ break
816
+ i = 0
817
+ for via in self.instances:
818
+ for instance in new_instances:
819
+ from_layer = self.data.layer_names[0]
820
+ to_layer = self.data.layer_names[-1]
821
+ from_layer = next(l for layer_name, l in self._pedb.stackup.layers.items() if l.name == from_layer)
822
+ to_layer = next(l for layer_name, l in self._pedb.stackup.layers.items() if l.name == to_layer)
823
+ padstack_instance = PadstackInstance.create(
824
+ layout=layout,
825
+ net=via.net,
826
+ name=generate_unique_name(instance.name),
827
+ padstack_def=instance,
828
+ position_x=via.position[0],
829
+ position_y=via.position[1],
830
+ rotation=0.0,
831
+ top_layer=from_layer,
832
+ bottom_layer=to_layer,
833
+ solder_ball_layer=None,
834
+ layer_map=None,
835
+ )
836
+ padstack_instance.is_layout_pin = via.is_pin
837
+ i += 1
838
+ via.delete()
839
+ self._pedb.logger.info("Created {} new microvias.".format(i))
840
+ return new_instances
841
+
842
+ # TODO check if update layer name is needed.