pyedb 0.50.0__py3-none-any.whl → 0.51.2__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 (75) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_ports_sources.py +79 -239
  3. pyedb/configuration/configuration.py +27 -0
  4. pyedb/dotnet/clr_module.py +9 -3
  5. pyedb/dotnet/database/cell/hierarchy/component.py +3 -3
  6. pyedb/dotnet/database/cell/layout.py +10 -1
  7. pyedb/dotnet/database/dotnet/database.py +0 -2
  8. pyedb/dotnet/database/edb_data/padstacks_data.py +13 -0
  9. pyedb/dotnet/database/layout_validation.py +17 -13
  10. pyedb/dotnet/database/modeler.py +0 -1
  11. pyedb/dotnet/edb.py +7 -1
  12. pyedb/generic/design_types.py +183 -62
  13. pyedb/grpc/database/components.py +604 -652
  14. pyedb/grpc/database/control_file.py +597 -155
  15. pyedb/grpc/database/definition/component_def.py +17 -14
  16. pyedb/grpc/database/definition/materials.py +27 -27
  17. pyedb/grpc/database/definition/package_def.py +8 -8
  18. pyedb/grpc/database/definition/padstack_def.py +31 -33
  19. pyedb/grpc/database/definitions.py +36 -2
  20. pyedb/grpc/database/geometry/arc_data.py +5 -5
  21. pyedb/grpc/database/geometry/point_3d_data.py +3 -3
  22. pyedb/grpc/database/geometry/polygon_data.py +5 -5
  23. pyedb/grpc/database/hfss.py +412 -395
  24. pyedb/grpc/database/hierarchy/component.py +67 -58
  25. pyedb/grpc/database/hierarchy/pin_pair_model.py +6 -6
  26. pyedb/grpc/database/hierarchy/pingroup.py +13 -11
  27. pyedb/grpc/database/hierarchy/s_parameter_model.py +1 -1
  28. pyedb/grpc/database/hierarchy/spice_model.py +1 -1
  29. pyedb/grpc/database/layers/layer.py +2 -2
  30. pyedb/grpc/database/layers/stackup_layer.py +26 -23
  31. pyedb/grpc/database/layout/layout.py +12 -12
  32. pyedb/grpc/database/layout/voltage_regulator.py +8 -8
  33. pyedb/grpc/database/layout_validation.py +58 -7
  34. pyedb/grpc/database/modeler.py +248 -245
  35. pyedb/grpc/database/net/differential_pair.py +4 -4
  36. pyedb/grpc/database/net/extended_net.py +7 -8
  37. pyedb/grpc/database/net/net.py +57 -46
  38. pyedb/grpc/database/nets.py +362 -116
  39. pyedb/grpc/database/padstacks.py +259 -178
  40. pyedb/grpc/database/ports/ports.py +23 -17
  41. pyedb/grpc/database/primitive/padstack_instance.py +45 -30
  42. pyedb/grpc/database/primitive/path.py +6 -6
  43. pyedb/grpc/database/primitive/polygon.py +9 -9
  44. pyedb/grpc/database/primitive/primitive.py +21 -21
  45. pyedb/grpc/database/primitive/rectangle.py +1 -1
  46. pyedb/grpc/database/simulation_setup/hfss_advanced_settings.py +1 -1
  47. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +1 -1
  48. pyedb/grpc/database/simulation_setup/hfss_settings_options.py +1 -1
  49. pyedb/grpc/database/simulation_setup/hfss_simulation_settings.py +6 -6
  50. pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +2 -2
  51. pyedb/grpc/database/simulation_setup/raptor_x_simulation_settings.py +2 -2
  52. pyedb/grpc/database/simulation_setup/raptor_x_simulation_setup.py +1 -1
  53. pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +3 -3
  54. pyedb/grpc/database/siwave.py +226 -214
  55. pyedb/grpc/database/source_excitations.py +307 -40
  56. pyedb/grpc/database/stackup.py +461 -283
  57. pyedb/grpc/database/terminal/bundle_terminal.py +12 -12
  58. pyedb/grpc/database/terminal/edge_terminal.py +6 -5
  59. pyedb/grpc/database/terminal/padstack_instance_terminal.py +13 -13
  60. pyedb/grpc/database/terminal/pingroup_terminal.py +12 -12
  61. pyedb/grpc/database/terminal/point_terminal.py +6 -6
  62. pyedb/grpc/database/terminal/terminal.py +26 -26
  63. pyedb/grpc/database/utility/heat_sink.py +5 -5
  64. pyedb/grpc/database/utility/hfss_extent_info.py +21 -21
  65. pyedb/grpc/database/utility/layout_statistics.py +13 -13
  66. pyedb/grpc/database/utility/rlc.py +3 -3
  67. pyedb/grpc/database/utility/sources.py +1 -1
  68. pyedb/grpc/database/utility/sweep_data_distribution.py +1 -1
  69. pyedb/grpc/edb.py +542 -739
  70. pyedb/grpc/edb_init.py +50 -3
  71. {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/METADATA +1 -1
  72. {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/RECORD +74 -75
  73. pyedb/grpc/database/utility/simulation_configuration.py +0 -3305
  74. {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/LICENSE +0 -0
  75. {pyedb-0.50.0.dist-info → pyedb-0.51.2.dist-info}/WHEEL +0 -0
@@ -33,21 +33,158 @@ from pyedb.misc.misc import list_installed_ansysem
33
33
 
34
34
 
35
35
  def convert_technology_file(tech_file, edbversion=None, control_file=None):
36
- """Convert a technology file to edb control file (xml).
36
+ """Convert a technology file to EDB control file (XML).
37
37
 
38
- Parameters
39
- ----------
40
- tech_file : str
41
- Full path to technology file
42
- edbversion : str, optional
43
- Edb version to use. Default is `None` to use latest available version of Edb.
44
- control_file : str, optional
45
- Control file output file. Default is `None` to use same path and same name of `tech_file`.
46
-
47
- Returns
48
- -------
49
- str
50
- Control file full path if created.
38
+ Parameters
39
+ ----------
40
+ tech_file : str
41
+ Full path to technology file.
42
+ edbversion : str, optional
43
+ EDB version to use. If ``None``, uses latest available version.
44
+ control_file : str, optional
45
+ Output control file path. If ``None``, uses same path and name as ``tech_file``.
46
+
47
+ Returns
48
+ -------
49
+ str or bool
50
+ Full path to created control file if successful, ``False`` otherwise.
51
+
52
+ Notes
53
+ -----
54
+ This function is only supported on Linux systems.
55
+
56
+ Example
57
+ -------
58
+ # Example 1: Converting a technology file to control file
59
+ >>> converted_file = convert_technology_file(
60
+ >>> tech_file="/path/to/tech.t",
61
+ >>> edbversion="2025.2",
62
+ >>> control_file="/path/to/output.xml"
63
+ >>> )
64
+ >>> if converted_file:
65
+ >>> print(f"Converted to: {converted_file}")
66
+
67
+ # Example 2: Creating a material
68
+ >>> from pyedb import ControlFileMaterial
69
+ >>> material = ControlFileMaterial(
70
+ >>> "Copper",
71
+ >>> {"Permittivity": 1.0, "Conductivity": 5.8e7}
72
+ >>> )
73
+
74
+ # Example 3: Creating a dielectric layer
75
+ >>> from pyedb import ControlFileDielectric
76
+ >>> dielectric = ControlFileDielectric(
77
+ >>> "Core",
78
+ >>> {"Thickness": "0.2mm", "Material": "FR4"}
79
+ >>> )
80
+
81
+ # Example 4: Creating a signal layer
82
+ >>> from pyedb import ControlFileLayer
83
+ >>> signal_layer = ControlFileLayer(
84
+ >>> "TopLayer",
85
+ >>> {"Type": "signal", "Material": "Copper", "Thickness": "0.035mm"}
86
+ >>> )
87
+
88
+ # Example 5: Creating a via layer
89
+ >>> from pyedb import ControlFileVia
90
+ >>> via_layer = ControlFileVia(
91
+ >>> "Via1",
92
+ >>> {"StartLayer": "TopLayer", "StopLayer": "BottomLayer"}
93
+ >>> )
94
+ >>> via_layer.create_via_group = True
95
+ >>> via_layer.tolerance = "0.1mm"
96
+
97
+ # Example 6: Managing stackup
98
+ >>> from pyedb import ControlFileStackup
99
+ >>> stackup = ControlFileStackup(units="mm")
100
+ >>> stackup.add_material("FR4", permittivity=4.4, dielectric_loss_tg=0.02)
101
+ >>> stackup.add_layer("L1", elevation=0, material="Copper", thickness=0.035)
102
+ >>> stackup.add_dielectric("Diel1", material="FR4", thickness=0.2)
103
+ >>> stackup.add_via("Via1", start_layer="L1", stop_layer="L2")
104
+
105
+ # Example 7: Configuring import options
106
+ >>> from pyedb import ControlFileImportOptions
107
+ >>> import_ops = ControlFileImportOptions()
108
+ >>> import_ops.auto_close = True
109
+ >>> import_ops.defeature_tolerance = 0.001
110
+
111
+ # Example 8: Setting up simulation extents
112
+ >>> from pyedb import ControlExtent
113
+ >>> extent = ControlExtent(
114
+ >>> type="Conforming",
115
+ >>> diel_hactor=0.3,
116
+ >>> airbox_hfactor=0.5
117
+ >>> )
118
+
119
+ # Example 9: Creating circuit ports
120
+ >>> from pyedb import ControlCircuitPt
121
+ >>> port = ControlCircuitPt("Port1", 0, 0, "TopLayer", 1, 0, "TopLayer", 50)
122
+
123
+ # Example 10: Managing components
124
+ >>> from pyedb import ControlFileComponent
125
+ >>> comp = ControlFileComponent()
126
+ >>> comp.refdes = "U1"
127
+ >>> comp.add_pin("Pin1", 0.5, 0.5, "TopLayer")
128
+ >>> comp.add_port("Port1", 50, "Pin1", refpin="GND")
129
+
130
+ # Example 11: Component management
131
+ >>> from pyedb import ControlFileComponents
132
+ >>> components = ControlFileComponents()
133
+ >>> ic = components.add_component("U1", "BGA", "IC", die_type="Flip chip")
134
+ >>> ic.add_pin("A1", 1.0, 1.0, "TopLayer")
135
+
136
+ # Example 12: Boundary setup
137
+ >>> from pyedb import ControlFileBoundaries
138
+ >>> boundaries = ControlFileBoundaries()
139
+ >>> boundaries.add_port("Port1", 0, 0, "L1", 1, 0, "L1", 50)
140
+ >>> boundaries.add_extent(diel_hactor=0.3)
141
+
142
+ # Example 13: Frequency sweep configuration
143
+ >>> from pyedb import ControlFileSweep
144
+ >>> sweep = ControlFileSweep(
145
+ >>> "Sweep1", "1GHz", "10GHz", "0.1GHz",
146
+ >>> "Interpolating", "LinearStep", True
147
+ >>> )
148
+
149
+ # Example 14: Mesh operation setup
150
+ >>> from pyedb import ControlFileMeshOp
151
+ >>> mesh_op = ControlFileMeshOp(
152
+ >>> "FineMesh", "Region1", "MeshOperationSkinDepth",
153
+ >>> {"Net1": "TopLayer"}
154
+ >>> )
155
+ >>> mesh_op.skin_depth = "1um"
156
+
157
+ # Example 15: Simulation setup configuration
158
+ >>> from pyedb import ControlFileSetup
159
+ >>> setup = ControlFileSetup("SimSetup1")
160
+ >>> setup.frequency = "5GHz"
161
+ >>> setup.add_sweep("Sweep1", "1GHz", "10GHz", "0.5GHz")
162
+ >>> setup.add_mesh_operation("Mesh1", "Chip", "MeshOperationLength", {"PWR": "Top"})
163
+
164
+ # Example 16: Setup management
165
+ >>> from pyedb import ControlFileSetups
166
+ >>> setups = ControlFileSetups()
167
+ >>> sim_setup = setups.add_setup("MySetup", "10GHz")
168
+ >>> sim_setup.add_sweep("Swp1", "1GHz", "20GHz", 100, step_type="LinearCount")
169
+
170
+ # Example 17: Main control file creation
171
+ >>> from pyedb import ControlFile
172
+
173
+ # Create from scratch
174
+ >>> ctrl = ControlFile()
175
+ >>> ctrl.stackup.add_material("Copper", conductivity=5.8e7)
176
+ >>> ctrl.stackup.add_layer("Signal", thickness=0.035, material="Copper")
177
+ >>> ctrl.boundaries.add_port("Input", 0, 0, "Signal", 1, 0, "Signal", 50)
178
+ >>> ctrl.write_xml("/path/to/control.xml")
179
+
180
+ # Parse existing file
181
+ >>> ctrl = ControlFile(xml_input="/path/to/existing.xml")
182
+
183
+ # Convert technology file
184
+ >>> ctrl = ControlFile(tecnhology="/path/to/tech.t")
185
+
186
+ # Apply layer mapping
187
+ >>> ctrl.parse_layer_map("/path/to/layer_map.txt")
51
188
  """
52
189
  if is_linux: # pragma: no cover
53
190
  if not edbversion:
@@ -56,7 +193,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
56
193
  base_path = env_path(edbversion)
57
194
  sys.path.append(base_path)
58
195
  else:
59
- pyedb_logger.error("No Edb installation found. Check environment variables")
196
+ pyedb_logger.error("No EDB installation found. Check environment variables")
60
197
  return False
61
198
  os.environ["HELIC_ROOT"] = os.path.join(base_path, "helic")
62
199
  if os.getenv("ANSYSLMD_LICENCE_FILE", None) is None:
@@ -103,13 +240,23 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
103
240
  p = subprocess.Popen(command, env=my_env)
104
241
  p.wait()
105
242
  if os.path.exists(control_file):
106
- pyedb_logger.info("Xml file created.")
243
+ pyedb_logger.info("XML file created.")
107
244
  return control_file
108
245
  pyedb_logger.error("Technology files are supported only in Linux. Use control file instead.")
109
246
  return False
110
247
 
111
248
 
112
249
  class ControlProperty:
250
+ """Represents a property in the control file with name, value, and type.
251
+
252
+ Parameters
253
+ ----------
254
+ property_name : str
255
+ Name of the property.
256
+ value : str, float, or list
257
+ Value of the property.
258
+ """
259
+
113
260
  def __init__(self, property_name, value):
114
261
  self.name = property_name
115
262
  self.value = value
@@ -125,6 +272,13 @@ class ControlProperty:
125
272
  pass
126
273
 
127
274
  def _write_xml(self, root):
275
+ """Write the property to XML element.
276
+
277
+ Parameters
278
+ ----------
279
+ root : xml.etree.ElementTree.Element
280
+ Parent XML element to append to.
281
+ """
128
282
  try:
129
283
  if self.type == 0:
130
284
  content = ET.SubElement(root, self.name)
@@ -137,6 +291,16 @@ class ControlProperty:
137
291
 
138
292
 
139
293
  class ControlFileMaterial:
294
+ """Represents a material in the control file.
295
+
296
+ Parameters
297
+ ----------
298
+ name : str
299
+ Material name.
300
+ properties : dict
301
+ Material properties dictionary.
302
+ """
303
+
140
304
  def __init__(self, name, properties):
141
305
  self.name = name
142
306
  self.properties = {}
@@ -144,6 +308,13 @@ class ControlFileMaterial:
144
308
  self.properties[name] = ControlProperty(name, property)
145
309
 
146
310
  def _write_xml(self, root):
311
+ """Write material to XML element.
312
+
313
+ Parameters
314
+ ----------
315
+ root : xml.etree.ElementTree.Element
316
+ Parent XML element to append to.
317
+ """
147
318
  content = ET.SubElement(root, "Material")
148
319
  content.set("Name", self.name)
149
320
  for property_name, property in self.properties.items():
@@ -151,6 +322,16 @@ class ControlFileMaterial:
151
322
 
152
323
 
153
324
  class ControlFileDielectric:
325
+ """Represents a dielectric layer in the control file.
326
+
327
+ Parameters
328
+ ----------
329
+ name : str
330
+ Layer name.
331
+ properties : dict
332
+ Layer properties dictionary.
333
+ """
334
+
154
335
  def __init__(self, name, properties):
155
336
  self.name = name
156
337
  self.properties = {}
@@ -158,6 +339,13 @@ class ControlFileDielectric:
158
339
  self.properties[name] = prop
159
340
 
160
341
  def _write_xml(self, root):
342
+ """Write dielectric layer to XML element.
343
+
344
+ Parameters
345
+ ----------
346
+ root : xml.etree.ElementTree.Element
347
+ Parent XML element to append to.
348
+ """
161
349
  content = ET.SubElement(root, "Layer")
162
350
  for property_name, property in self.properties.items():
163
351
  if not property_name == "Index":
@@ -165,6 +353,16 @@ class ControlFileDielectric:
165
353
 
166
354
 
167
355
  class ControlFileLayer:
356
+ """Represents a general layer in the control file.
357
+
358
+ Parameters
359
+ ----------
360
+ name : str
361
+ Layer name.
362
+ properties : dict
363
+ Layer properties dictionary.
364
+ """
365
+
168
366
  def __init__(self, name, properties):
169
367
  self.name = name
170
368
  self.properties = {}
@@ -172,6 +370,13 @@ class ControlFileLayer:
172
370
  self.properties[name] = prop
173
371
 
174
372
  def _write_xml(self, root):
373
+ """Write layer to XML element.
374
+
375
+ Parameters
376
+ ----------
377
+ root : xml.etree.ElementTree.Element
378
+ Parent XML element to append to.
379
+ """
175
380
  content = ET.SubElement(root, "Layer")
176
381
  content.set("Color", self.properties.get("Color", "#5c4300"))
177
382
  if self.properties.get("Elevation"):
@@ -196,6 +401,16 @@ class ControlFileLayer:
196
401
 
197
402
 
198
403
  class ControlFileVia(ControlFileLayer):
404
+ """Represents a via layer in the control file.
405
+
406
+ Parameters
407
+ ----------
408
+ name : str
409
+ Via name.
410
+ properties : dict
411
+ Via properties dictionary.
412
+ """
413
+
199
414
  def __init__(self, name, properties):
200
415
  ControlFileLayer.__init__(self, name, properties)
201
416
  self.create_via_group = False
@@ -209,6 +424,13 @@ class ControlFileVia(ControlFileLayer):
209
424
  self.snap_tolerance = 3
210
425
 
211
426
  def _write_xml(self, root):
427
+ """Write via to XML element.
428
+
429
+ Parameters
430
+ ----------
431
+ root : xml.etree.ElementTree.Element
432
+ Parent XML element to append to.
433
+ """
212
434
  content = ET.SubElement(root, "Layer")
213
435
  content.set("Color", self.properties.get("Color", "#5c4300"))
214
436
  if self.properties.get("Elevation"):
@@ -240,7 +462,13 @@ class ControlFileVia(ControlFileLayer):
240
462
 
241
463
 
242
464
  class ControlFileStackup:
243
- """Class that manages the Stackup info."""
465
+ """Manages stackup information for the control file.
466
+
467
+ Parameters
468
+ ----------
469
+ units : str, optional
470
+ Length units (e.g., "mm", "um"). Default is "mm".
471
+ """
244
472
 
245
473
  def __init__(self, units="mm"):
246
474
  self._materials = {}
@@ -253,45 +481,42 @@ class ControlFileStackup:
253
481
 
254
482
  @property
255
483
  def vias(self):
256
- """Via list.
484
+ """List of via objects.
257
485
 
258
486
  Returns
259
487
  -------
260
- list of :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileVia`
261
-
488
+ list of ControlFileVia
262
489
  """
263
490
  return self._vias
264
491
 
265
492
  @property
266
493
  def materials(self):
267
- """Material list.
494
+ """Dictionary of material objects.
268
495
 
269
496
  Returns
270
497
  -------
271
- list of :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileMaterial`
272
-
498
+ dict
499
+ Dictionary of material names to ControlFileMaterial objects.
273
500
  """
274
501
  return self._materials
275
502
 
276
503
  @property
277
504
  def dielectrics(self):
278
- """Dielectric layer list.
505
+ """List of dielectric layers.
279
506
 
280
507
  Returns
281
508
  -------
282
- list of :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileLayer`
283
-
509
+ list of ControlFileDielectric
284
510
  """
285
511
  return self._dielectrics
286
512
 
287
513
  @property
288
514
  def layers(self):
289
- """Layer list.
515
+ """List of general layers.
290
516
 
291
517
  Returns
292
518
  -------
293
- list of :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileLayer`
294
-
519
+ list of ControlFileLayer
295
520
  """
296
521
  return self._layers
297
522
 
@@ -304,27 +529,27 @@ class ControlFileStackup:
304
529
  conductivity=0.0,
305
530
  properties=None,
306
531
  ):
307
- """Add a new material with specific properties.
532
+ """Add a new material.
308
533
 
309
534
  Parameters
310
535
  ----------
311
536
  material_name : str
312
537
  Material name.
313
538
  permittivity : float, optional
314
- Material permittivity. The default is ``1.0``.
539
+ Relative permittivity. Default is ``1.0``.
315
540
  dielectric_loss_tg : float, optional
316
- Material tangent losses. The default is ``0.0``.
541
+ Dielectric loss tangent. Default is ``0.0``.
317
542
  permeability : float, optional
318
- Material permeability. The default is ``1.0``.
543
+ Relative permeability. Default is ``1.0``.
319
544
  conductivity : float, optional
320
- Material conductivity. The default is ``0.0``.
545
+ Conductivity (S/m). Default is ``0.0``.
321
546
  properties : dict, optional
322
- Specific material properties. The default is ``None``.
323
- Dictionary with key and material property value.
547
+ Additional material properties. Overrides default parameters.
324
548
 
325
549
  Returns
326
550
  -------
327
- :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileMaterial`
551
+ ControlFileMaterial
552
+ Created material object.
328
553
  """
329
554
  if isinstance(properties, dict):
330
555
  self._materials[material_name] = ControlFileMaterial(material_name, properties)
@@ -359,26 +584,26 @@ class ControlFileStackup:
359
584
  layer_name : str
360
585
  Layer name.
361
586
  elevation : float
362
- Layer elevation.
587
+ Layer elevation (Z-position).
363
588
  material : str
364
- Material for the layer.
589
+ Material name.
365
590
  gds_type : int
366
- GDS type assigned on the layer. The value must be the same as in the GDS file otherwise geometries won't be
367
- imported.
591
+ GDS data type for layer.
368
592
  target_layer : str
369
- Layer name assigned in EDB or HFSS 3D layout after import.
593
+ Target layer name in EDB/HFSS.
370
594
  thickness : float
371
- Layer thickness
372
- layer_type : str
373
- Define the layer type, default value for a layer is ``"conductor"``
374
- solve_inside : bool
375
- When ``True`` solver will solve inside metal, and not id ``False``. Default value is ``True``.
376
- properties : dict
377
- Dictionary with key and property value.
595
+ Layer thickness.
596
+ layer_type : str, optional
597
+ Layer type ("conductor", "signal", etc.). Default is "conductor".
598
+ solve_inside : bool, optional
599
+ Whether to solve inside metal. Default is ``True``.
600
+ properties : dict, optional
601
+ Additional layer properties. Overrides default parameters.
378
602
 
379
603
  Returns
380
604
  -------
381
- :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileLayer`
605
+ ControlFileLayer
606
+ Created layer object.
382
607
  """
383
608
  if isinstance(properties, dict):
384
609
  self._layers.append(ControlFileLayer(layer_name, properties))
@@ -407,31 +632,29 @@ class ControlFileStackup:
407
632
  base_layer=None,
408
633
  add_on_top=True,
409
634
  ):
410
- """Add a new dielectric.
635
+ """Add a new dielectric layer.
411
636
 
412
637
  Parameters
413
638
  ----------
414
639
  layer_name : str
415
- Layer name.
640
+ Dielectric layer name.
416
641
  layer_index : int, optional
417
- Dielectric layer index as they must be stacked. If not provided the layer index will be incremented.
642
+ Stacking order index. Auto-assigned if ``None``.
418
643
  material : str
419
644
  Material name.
420
645
  thickness : float
421
646
  Layer thickness.
422
- properties : dict
423
- Dictionary with key and property value.
424
- base_layer : str, optional
425
- Layer name used for layer placement. Default value is ``None``. This option is used for inserting
426
- dielectric layer between two existing ones. When no argument is provided the dielectric layer will be placed
427
- on top of the stacked ones.
428
- method : bool, Optional.
429
- Provides the method to use when the argument ``base_layer`` is provided. When ``True`` the layer is added
430
- on top on the base layer, when ``False`` it will be added below.
647
+ properties : dict, optional
648
+ Additional properties. Overrides default parameters.
649
+ base_layer : str, optional
650
+ Existing layer name for relative placement.
651
+ add_on_top : bool, optional
652
+ Whether to add on top of base layer. Default is ``True``.
431
653
 
432
654
  Returns
433
655
  -------
434
- :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileDielectric`
656
+ ControlFileDielectric
657
+ Created dielectric layer object.
435
658
  """
436
659
  if isinstance(properties, dict):
437
660
  self._dielectrics.append(ControlFileDielectric(layer_name, properties))
@@ -481,35 +704,36 @@ class ControlFileStackup:
481
704
  Parameters
482
705
  ----------
483
706
  layer_name : str
484
- Layer name.
707
+ Via layer name.
485
708
  material : str
486
- Define the material for this layer.
709
+ Material name.
487
710
  gds_type : int
488
- Define the gds type.
711
+ GDS data type for via layer.
489
712
  target_layer : str
490
- Target layer used after layout import in EDB and HFSS 3D layout.
713
+ Target layer name in EDB/HFSS.
491
714
  start_layer : str
492
- Define the start layer for the via
715
+ Starting layer name.
493
716
  stop_layer : str
494
- Define the stop layer for the via.
495
- solve_inside : bool
496
- When ``True`` solve inside this layer is anbled. Default value is ``True``.
497
- via_group_method : str
498
- Define the via group method, default value is ``"proximity"``
499
- via_group_tol : float
500
- Define the via group tolerance.
501
- via_group_persistent : bool
502
- When ``True`` activated otherwise when ``False``is deactivated. Default value is ``True``.
503
- snap_via_group_method : str
504
- Define the via group method, default value is ``"distance"``
505
- snap_via_group_tol : float
506
- Define the via group tolerance, default value is 10e-9.
507
- properties : dict
508
- Dictionary with key and property value.
717
+ Stopping layer name.
718
+ solve_inside : bool, optional
719
+ Whether to solve inside via. Default is ``True``.
720
+ via_group_method : str, optional
721
+ Via grouping method. Default is "proximity".
722
+ via_group_tol : float, optional
723
+ Via grouping tolerance. Default is 1e-6.
724
+ via_group_persistent : bool, optional
725
+ Whether via groups are persistent. Default is ``True``.
726
+ snap_via_group_method : str, optional
727
+ Snap via group method. Default is "distance".
728
+ snap_via_group_tol : float, optional
729
+ Snap via group tolerance. Default is 10e-9.
730
+ properties : dict, optional
731
+ Additional properties. Overrides default parameters.
509
732
 
510
733
  Returns
511
734
  -------
512
- :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileVia`
735
+ ControlFileVia
736
+ Created via object.
513
737
  """
514
738
  if isinstance(properties, dict):
515
739
  self._vias.append(ControlFileVia(layer_name, properties))
@@ -533,6 +757,13 @@ class ControlFileStackup:
533
757
  return self._vias[-1]
534
758
 
535
759
  def _write_xml(self, root):
760
+ """Write stackup to XML element.
761
+
762
+ Parameters
763
+ ----------
764
+ root : xml.etree.ElementTree.Element
765
+ Parent XML element to append to.
766
+ """
536
767
  content = ET.SubElement(root, "Stackup")
537
768
  content.set("schemaVersion", "1.0")
538
769
  materials = ET.SubElement(content, "Materials")
@@ -559,7 +790,7 @@ class ControlFileStackup:
559
790
 
560
791
 
561
792
  class ControlFileImportOptions:
562
- """Import Options."""
793
+ """Manages import options for the control file."""
563
794
 
564
795
  def __init__(self):
565
796
  self.auto_close = False
@@ -579,6 +810,13 @@ class ControlFileImportOptions:
579
810
  self.delte_empty_non_laminate_signal_layers = False
580
811
 
581
812
  def _write_xml(self, root):
813
+ """Write import options to XML element.
814
+
815
+ Parameters
816
+ ----------
817
+ root : xml.etree.ElementTree.Element
818
+ Parent XML element to append to.
819
+ """
582
820
  content = ET.SubElement(root, "ImportOptions")
583
821
  content.set("AutoClose", str(self.auto_close).lower())
584
822
  if self.round_to != 0:
@@ -603,7 +841,29 @@ class ControlFileImportOptions:
603
841
 
604
842
 
605
843
  class ControlExtent:
606
- """Extent options."""
844
+ """Represents extent options for boundaries.
845
+
846
+ Parameters
847
+ ----------
848
+ type : str, optional
849
+ Extent type. Default is "bbox".
850
+ dieltype : str, optional
851
+ Dielectric extent type. Default is "bbox".
852
+ diel_hactor : float, optional
853
+ Dielectric horizontal factor. Default is 0.25.
854
+ airbox_hfactor : float, optional
855
+ Airbox horizontal factor. Default is 0.25.
856
+ airbox_vr_p : float, optional
857
+ Airbox vertical factor (positive). Default is 0.25.
858
+ airbox_vr_n : float, optional
859
+ Airbox vertical factor (negative). Default is 0.25.
860
+ useradiation : bool, optional
861
+ Use radiation boundary. Default is ``True``.
862
+ honor_primitives : bool, optional
863
+ Honor primitives. Default is ``True``.
864
+ truncate_at_gnd : bool, optional
865
+ Truncate at ground. Default is ``True``.
866
+ """
607
867
 
608
868
  def __init__(
609
869
  self,
@@ -628,6 +888,13 @@ class ControlExtent:
628
888
  self.truncate_at_gnd = truncate_at_gnd
629
889
 
630
890
  def _write_xml(self, root):
891
+ """Write extent options to XML element.
892
+
893
+ Parameters
894
+ ----------
895
+ root : xml.etree.ElementTree.Element
896
+ Parent XML element to append to.
897
+ """
631
898
  content = ET.SubElement(root, "Extents")
632
899
  content.set("Type", self.type)
633
900
  content.set("DielType", self.dieltype)
@@ -641,7 +908,27 @@ class ControlExtent:
641
908
 
642
909
 
643
910
  class ControlCircuitPt:
644
- """Circuit Port."""
911
+ """Represents a circuit port.
912
+
913
+ Parameters
914
+ ----------
915
+ name : str
916
+ Port name.
917
+ x1 : float
918
+ X-coordinate of first point.
919
+ y1 : float
920
+ Y-coordinate of first point.
921
+ lay1 : str
922
+ Layer of first point.
923
+ x2 : float
924
+ X-coordinate of second point.
925
+ y2 : float
926
+ Y-coordinate of second point.
927
+ lay2 : str
928
+ Layer of second point.
929
+ z0 : float
930
+ Characteristic impedance.
931
+ """
645
932
 
646
933
  def __init__(self, name, x1, y1, lay1, x2, y2, lay2, z0):
647
934
  self.name = name
@@ -654,6 +941,13 @@ class ControlCircuitPt:
654
941
  self.z0 = z0
655
942
 
656
943
  def _write_xml(self, root):
944
+ """Write circuit port to XML element.
945
+
946
+ Parameters
947
+ ----------
948
+ root : xml.etree.ElementTree.Element
949
+ Parent XML element to append to.
950
+ """
657
951
  content = ET.SubElement(root, "CircuitPortPt")
658
952
  content.set("Name", self.name)
659
953
  content.set("x1", self.x1)
@@ -666,7 +960,7 @@ class ControlCircuitPt:
666
960
 
667
961
 
668
962
  class ControlFileComponent:
669
- """Components."""
963
+ """Represents a component in the control file."""
670
964
 
671
965
  def __init__(self):
672
966
  self.refdes = "U1"
@@ -682,9 +976,39 @@ class ControlFileComponent:
682
976
  self.ports = []
683
977
 
684
978
  def add_pin(self, name, x, y, layer):
979
+ """Add a pin to the component.
980
+
981
+ Parameters
982
+ ----------
983
+ name : str
984
+ Pin name.
985
+ x : float
986
+ X-coordinate.
987
+ y : float
988
+ Y-coordinate.
989
+ layer : str
990
+ Layer name.
991
+ """
685
992
  self.pins.append({"Name": name, "x": x, "y": y, "Layer": layer})
686
993
 
687
994
  def add_port(self, name, z0, pospin, refpin=None, pos_type="pin", ref_type="pin"):
995
+ """Add a port to the component.
996
+
997
+ Parameters
998
+ ----------
999
+ name : str
1000
+ Port name.
1001
+ z0 : float
1002
+ Characteristic impedance.
1003
+ pospin : str
1004
+ Positive pin/group name.
1005
+ refpin : str, optional
1006
+ Reference pin/group name.
1007
+ pos_type : str, optional
1008
+ Positive element type ("pin" or "pingroup"). Default is "pin".
1009
+ ref_type : str, optional
1010
+ Reference element type ("pin", "pingroup", or "net"). Default is "pin".
1011
+ """
688
1012
  args = {"Name": name, "Z0": z0}
689
1013
  if pos_type == "pin":
690
1014
  args["PosPin"] = pospin
@@ -700,6 +1024,13 @@ class ControlFileComponent:
700
1024
  self.ports.append(args)
701
1025
 
702
1026
  def _write_xml(self, root):
1027
+ """Write component to XML element.
1028
+
1029
+ Parameters
1030
+ ----------
1031
+ root : xml.etree.ElementTree.Element
1032
+ Parent XML element to append to.
1033
+ """
703
1034
  content = ET.SubElement(root, "GDS_COMPONENT")
704
1035
  for p in self.pins:
705
1036
  prop = ET.SubElement(content, "GDS_PIN")
@@ -725,31 +1056,32 @@ class ControlFileComponent:
725
1056
 
726
1057
 
727
1058
  class ControlFileComponents:
728
- """Class for component management."""
1059
+ """Manages components for the control file."""
729
1060
 
730
1061
  def __init__(self):
731
1062
  self.units = "um"
732
1063
  self.components = []
733
1064
 
734
1065
  def add_component(self, ref_des, partname, component_type, die_type="None", solderball_shape="None"):
735
- """Create a new component.
1066
+ """Add a new component.
736
1067
 
737
1068
  Parameters
738
1069
  ----------
739
1070
  ref_des : str
740
- Reference Designator name.
1071
+ Reference designator.
741
1072
  partname : str
742
1073
  Part name.
743
1074
  component_type : str
744
- Component Type. Can be `"IC"`, `"IO"` or `"Other"`.
1075
+ Component type ("IC", "IO", or "Other").
745
1076
  die_type : str, optional
746
- Die Type. Can be `"None"`, `"Flip chip"` or `"Wire bond"`.
1077
+ Die type ("None", "Flip chip", or "Wire bond"). Default is "None".
747
1078
  solderball_shape : str, optional
748
- Solderball Type. Can be `"None"`, `"Cylinder"` or `"Spheroid"`.
1079
+ Solderball shape ("None", "Cylinder", or "Spheroid"). Default is "None".
749
1080
 
750
1081
  Returns
751
1082
  -------
752
-
1083
+ ControlFileComponent
1084
+ Created component object.
753
1085
  """
754
1086
  comp = ControlFileComponent()
755
1087
  comp.refdes = ref_des
@@ -762,7 +1094,13 @@ class ControlFileComponents:
762
1094
 
763
1095
 
764
1096
  class ControlFileBoundaries:
765
- """Boundaries management."""
1097
+ """Manages boundaries for the control file.
1098
+
1099
+ Parameters
1100
+ ----------
1101
+ units : str, optional
1102
+ Length units. Default is "um".
1103
+ """
766
1104
 
767
1105
  def __init__(self, units="um"):
768
1106
  self.ports = {}
@@ -772,30 +1110,31 @@ class ControlFileBoundaries:
772
1110
  self.units = units
773
1111
 
774
1112
  def add_port(self, name, x1, y1, layer1, x2, y2, layer2, z0=50):
775
- """Add a new port to the gds.
1113
+ """Add a port.
776
1114
 
777
1115
  Parameters
778
1116
  ----------
779
1117
  name : str
780
1118
  Port name.
781
- x1 : str
782
- Pin 1 x position.
783
- y1 : str
784
- Pin 1 y position.
1119
+ x1 : float
1120
+ X-coordinate of first point.
1121
+ y1 : float
1122
+ Y-coordinate of first point.
785
1123
  layer1 : str
786
- Pin 1 layer.
787
- x2 : str
788
- Pin 2 x position.
789
- y2 : str
790
- Pin 2 y position.
1124
+ Layer of first point.
1125
+ x2 : float
1126
+ X-coordinate of second point.
1127
+ y2 : float
1128
+ Y-coordinate of second point.
791
1129
  layer2 : str
792
- Pin 2 layer.
793
- z0 : str
794
- Characteristic impedance.
1130
+ Layer of second point.
1131
+ z0 : float, optional
1132
+ Characteristic impedance. Default is 50.
795
1133
 
796
1134
  Returns
797
1135
  -------
798
- :class:`pyedb.dotnet.database.edb_data.control_file.ControlCircuitPt`
1136
+ ControlCircuitPt
1137
+ Created port object.
799
1138
  """
800
1139
  self.ports[name] = ControlCircuitPt(name, str(x1), str(y1), layer1, str(x2), str(y2), layer2, str(z0))
801
1140
  return self.ports[name]
@@ -812,23 +1151,33 @@ class ControlFileBoundaries:
812
1151
  honor_primitives=True,
813
1152
  truncate_at_gnd=True,
814
1153
  ):
815
- """Add a new extent.
1154
+ """Add an extent.
816
1155
 
817
1156
  Parameters
818
1157
  ----------
819
- type
820
- dieltype
821
- diel_hactor
822
- airbox_hfactor
823
- airbox_vr_p
824
- airbox_vr_n
825
- useradiation
826
- honor_primitives
827
- truncate_at_gnd
1158
+ type : str, optional
1159
+ Extent type. Default is "bbox".
1160
+ dieltype : str, optional
1161
+ Dielectric extent type. Default is "bbox".
1162
+ diel_hactor : float, optional
1163
+ Dielectric horizontal factor. Default is 0.25.
1164
+ airbox_hfactor : float, optional
1165
+ Airbox horizontal factor. Default is 0.25.
1166
+ airbox_vr_p : float, optional
1167
+ Airbox vertical factor (positive). Default is 0.25.
1168
+ airbox_vr_n : float, optional
1169
+ Airbox vertical factor (negative). Default is 0.25.
1170
+ useradiation : bool, optional
1171
+ Use radiation boundary. Default is ``True``.
1172
+ honor_primitives : bool, optional
1173
+ Honor primitives. Default is ``True``.
1174
+ truncate_at_gnd : bool, optional
1175
+ Truncate at ground. Default is ``True``.
828
1176
 
829
1177
  Returns
830
1178
  -------
831
-
1179
+ ControlExtent
1180
+ Created extent object.
832
1181
  """
833
1182
  self.extents.append(
834
1183
  ControlExtent(
@@ -846,6 +1195,13 @@ class ControlFileBoundaries:
846
1195
  return self.extents[-1]
847
1196
 
848
1197
  def _write_xml(self, root):
1198
+ """Write boundaries to XML element.
1199
+
1200
+ Parameters
1201
+ ----------
1202
+ root : xml.etree.ElementTree.Element
1203
+ Parent XML element to append to.
1204
+ """
849
1205
  content = ET.SubElement(root, "Boundaries")
850
1206
  content.set("LengthUnit", self.units)
851
1207
  for p in self.circuit_models.values():
@@ -859,6 +1215,26 @@ class ControlFileBoundaries:
859
1215
 
860
1216
 
861
1217
  class ControlFileSweep:
1218
+ """Represents a frequency sweep.
1219
+
1220
+ Parameters
1221
+ ----------
1222
+ name : str
1223
+ Sweep name.
1224
+ start : str
1225
+ Start frequency.
1226
+ stop : str
1227
+ Stop frequency.
1228
+ step : str
1229
+ Frequency step/count.
1230
+ sweep_type : str
1231
+ Sweep type ("Discrete" or "Interpolating").
1232
+ step_type : str
1233
+ Step type ("LinearStep", "DecadeCount", or "LinearCount").
1234
+ use_q3d : bool
1235
+ Whether to use Q3D for DC point.
1236
+ """
1237
+
862
1238
  def __init__(self, name, start, stop, step, sweep_type, step_type, use_q3d):
863
1239
  self.name = name
864
1240
  self.start = start
@@ -869,6 +1245,13 @@ class ControlFileSweep:
869
1245
  self.use_q3d = use_q3d
870
1246
 
871
1247
  def _write_xml(self, root):
1248
+ """Write sweep to XML element.
1249
+
1250
+ Parameters
1251
+ ----------
1252
+ root : xml.etree.ElementTree.Element
1253
+ Parent XML element to append to.
1254
+ """
872
1255
  sweep = ET.SubElement(root, "FreqSweep")
873
1256
  prop = ET.SubElement(sweep, "Name")
874
1257
  prop.text = self.name
@@ -889,6 +1272,20 @@ class ControlFileSweep:
889
1272
 
890
1273
 
891
1274
  class ControlFileMeshOp:
1275
+ """Represents a mesh operation.
1276
+
1277
+ Parameters
1278
+ ----------
1279
+ name : str
1280
+ Operation name.
1281
+ region : str
1282
+ Region name.
1283
+ type : str
1284
+ Operation type ("MeshOperationLength" or "MeshOperationSkinDepth").
1285
+ nets_layers : dict
1286
+ Dictionary of nets and layers.
1287
+ """
1288
+
892
1289
  def __init__(self, name, region, type, nets_layers):
893
1290
  self.name = name
894
1291
  self.region = name
@@ -904,6 +1301,13 @@ class ControlFileMeshOp:
904
1301
  self.region_solve_inside = False
905
1302
 
906
1303
  def _write_xml(self, root):
1304
+ """Write mesh operation to XML element.
1305
+
1306
+ Parameters
1307
+ ----------
1308
+ root : xml.etree.ElementTree.Element
1309
+ Parent XML element to append to.
1310
+ """
907
1311
  mop = ET.SubElement(root, "MeshOperation")
908
1312
  prop = ET.SubElement(mop, "Name")
909
1313
  prop.text = self.name
@@ -941,7 +1345,13 @@ class ControlFileMeshOp:
941
1345
 
942
1346
 
943
1347
  class ControlFileSetup:
944
- """Setup Class."""
1348
+ """Represents a simulation setup.
1349
+
1350
+ Parameters
1351
+ ----------
1352
+ name : str
1353
+ Setup name.
1354
+ """
945
1355
 
946
1356
  def __init__(self, name):
947
1357
  self.name = name
@@ -962,55 +1372,64 @@ class ControlFileSetup:
962
1372
  self.sweeps = []
963
1373
 
964
1374
  def add_sweep(self, name, start, stop, step, sweep_type="Interpolating", step_type="LinearStep", use_q3d=True):
965
- """Add a new sweep.
1375
+ """Add a frequency sweep.
966
1376
 
967
1377
  Parameters
968
1378
  ----------
969
1379
  name : str
970
1380
  Sweep name.
971
1381
  start : str
972
- Frequency start.
1382
+ Start frequency.
973
1383
  stop : str
974
- Frequency stop.
1384
+ Stop frequency.
975
1385
  step : str
976
- Frequency step or count.
977
- sweep_type : str
978
- Sweep type. It can be `"Discrete"` or `"Interpolating"`.
979
- step_type : str
980
- Sweep type. It can be `"LinearStep"`, `"DecadeCount"` or `"LinearCount"`.
981
- use_q3d
1386
+ Frequency step/count.
1387
+ sweep_type : str, optional
1388
+ Sweep type ("Discrete" or "Interpolating"). Default is "Interpolating".
1389
+ step_type : str, optional
1390
+ Step type ("LinearStep", "DecadeCount", or "LinearCount"). Default is "LinearStep".
1391
+ use_q3d : bool, optional
1392
+ Whether to use Q3D for DC point. Default is ``True``.
982
1393
 
983
1394
  Returns
984
1395
  -------
985
- :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileSweep`
1396
+ ControlFileSweep
1397
+ Created sweep object.
986
1398
  """
987
1399
  self.sweeps.append(ControlFileSweep(name, start, stop, step, sweep_type, step_type, use_q3d))
988
1400
  return self.sweeps[-1]
989
1401
 
990
1402
  def add_mesh_operation(self, name, region, type, nets_layers):
991
- """Add mesh operations.
1403
+ """Add a mesh operation.
992
1404
 
993
1405
  Parameters
994
1406
  ----------
995
1407
  name : str
996
- Mesh name.
1408
+ Operation name.
997
1409
  region : str
998
- Region to apply mesh operation.
1410
+ Region name.
999
1411
  type : str
1000
- Mesh operation type. It can be `"MeshOperationLength"` or `"MeshOperationSkinDepth"`.
1412
+ Operation type ("MeshOperationLength" or "MeshOperationSkinDepth").
1001
1413
  nets_layers : dict
1002
- Dictionary containing nets and layers on which apply mesh.
1414
+ Dictionary of nets and layers.
1003
1415
 
1004
1416
  Returns
1005
1417
  -------
1006
- :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileMeshOp`
1007
-
1418
+ ControlFileMeshOp
1419
+ Created mesh operation object.
1008
1420
  """
1009
1421
  mop = ControlFileMeshOp(name, region, type, nets_layers)
1010
1422
  self.mesh_operations.append(mop)
1011
1423
  return mop
1012
1424
 
1013
1425
  def _write_xml(self, root):
1426
+ """Write setup to XML element.
1427
+
1428
+ Parameters
1429
+ ----------
1430
+ root : xml.etree.ElementTree.Element
1431
+ Parent XML element to append to.
1432
+ """
1014
1433
  setups = ET.SubElement(root, "HFSSSetup")
1015
1434
  setups.set("schemaVersion", "1.0")
1016
1435
  setups.set("Name", self.name)
@@ -1056,24 +1475,25 @@ class ControlFileSetup:
1056
1475
 
1057
1476
 
1058
1477
  class ControlFileSetups:
1059
- """Setup manager class."""
1478
+ """Manages simulation setups."""
1060
1479
 
1061
1480
  def __init__(self):
1062
1481
  self.setups = []
1063
1482
 
1064
1483
  def add_setup(self, name, frequency):
1065
- """Add a new setup
1484
+ """Add a simulation setup.
1066
1485
 
1067
1486
  Parameters
1068
1487
  ----------
1069
1488
  name : str
1070
1489
  Setup name.
1071
1490
  frequency : str
1072
- Setup Frequency.
1491
+ Adaptive frequency.
1073
1492
 
1074
1493
  Returns
1075
1494
  -------
1076
- :class:`pyedb.dotnet.database.edb_data.control_file.ControlFileSetup`
1495
+ ControlFileSetup
1496
+ Created setup object.
1077
1497
  """
1078
1498
  setup = ControlFileSetup(name)
1079
1499
  setup.frequency = frequency
@@ -1081,13 +1501,30 @@ class ControlFileSetups:
1081
1501
  return setup
1082
1502
 
1083
1503
  def _write_xml(self, root):
1504
+ """Write setups to XML element.
1505
+
1506
+ Parameters
1507
+ ----------
1508
+ root : xml.etree.ElementTree.Element
1509
+ Parent XML element to append to.
1510
+ """
1084
1511
  content = ET.SubElement(root, "SimulationSetups")
1085
1512
  for setup in self.setups:
1086
1513
  setup._write_xml(content)
1087
1514
 
1088
1515
 
1089
1516
  class ControlFile:
1090
- """Control File Class. It helps the creation and modification of edb xml control files."""
1517
+ """Main class for EDB control file creation and management.
1518
+
1519
+ Parameters
1520
+ ----------
1521
+ xml_input : str, optional
1522
+ Path to existing XML file to parse.
1523
+ tecnhology : str, optional
1524
+ Path to technology file to convert.
1525
+ layer_map : str, optional
1526
+ Path to layer map file.
1527
+ """
1091
1528
 
1092
1529
  def __init__(self, xml_input=None, tecnhology=None, layer_map=None):
1093
1530
  self.stackup = ControlFileStackup()
@@ -1107,16 +1544,19 @@ class ControlFile:
1107
1544
  pass
1108
1545
 
1109
1546
  def parse_technology(self, tecnhology, edbversion=None):
1110
- """Parse technology files using Helic and convert it to xml file.
1547
+ """Parse a technology file and convert to XML control file.
1111
1548
 
1112
1549
  Parameters
1113
1550
  ----------
1114
- layer_map : str
1115
- Full path to technology file.
1551
+ tecnhology : str
1552
+ Path to technology file.
1553
+ edbversion : str, optional
1554
+ EDB version to use for conversion.
1116
1555
 
1117
1556
  Returns
1118
1557
  -------
1119
1558
  bool
1559
+ ``True`` if successful, ``False`` otherwise.
1120
1560
  """
1121
1561
  xml_temp = os.path.splitext(tecnhology)[0] + "_temp.xml"
1122
1562
  xml_temp = convert_technology_file(tech_file=tecnhology, edbversion=edbversion, control_file=xml_temp)
@@ -1124,17 +1564,17 @@ class ControlFile:
1124
1564
  return self.parse_xml(xml_temp)
1125
1565
 
1126
1566
  def parse_layer_map(self, layer_map):
1127
- """Parse layer map and adds info to the stackup info.
1128
- This operation must be performed after a tech file is imported.
1567
+ """Parse a layer map file and update stackup.
1129
1568
 
1130
1569
  Parameters
1131
1570
  ----------
1132
1571
  layer_map : str
1133
- Full path to `".map"` file.
1572
+ Path to layer map file.
1134
1573
 
1135
1574
  Returns
1136
1575
  -------
1137
-
1576
+ bool
1577
+ ``True`` if successful, ``False`` otherwise.
1138
1578
  """
1139
1579
  with open(layer_map, "r") as f:
1140
1580
  lines = f.readlines()
@@ -1174,16 +1614,17 @@ class ControlFile:
1174
1614
  return True
1175
1615
 
1176
1616
  def parse_xml(self, xml_input):
1177
- """Parse an xml and populate the class with materials and Stackup only.
1617
+ """Parse an XML control file and populate the object.
1178
1618
 
1179
1619
  Parameters
1180
1620
  ----------
1181
1621
  xml_input : str
1182
- Full path to xml.
1622
+ Path to XML control file.
1183
1623
 
1184
1624
  Returns
1185
1625
  -------
1186
1626
  bool
1627
+ ``True`` if successful, ``False`` otherwise.
1187
1628
  """
1188
1629
  tree = ET.parse(xml_input)
1189
1630
  root = tree.getroot()
@@ -1244,16 +1685,17 @@ class ControlFile:
1244
1685
  return True
1245
1686
 
1246
1687
  def write_xml(self, xml_output):
1247
- """Write xml to output file
1688
+ """Write control file to XML.
1248
1689
 
1249
1690
  Parameters
1250
1691
  ----------
1251
1692
  xml_output : str
1252
- Path to the output xml file.
1693
+ Output XML file path.
1253
1694
 
1254
1695
  Returns
1255
1696
  -------
1256
1697
  bool
1698
+ ``True`` if file created successfully, ``False`` otherwise.
1257
1699
  """
1258
1700
  control = ET.Element("{http://www.ansys.com/control}Control", attrib={"schemaVersion": "1.0"})
1259
1701
  self.stackup._write_xml(control)