Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: Import gd s #994

Merged
merged 15 commits into from
Jan 27, 2025
2 changes: 1 addition & 1 deletion examples/legacy_standalone/10_GDS_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
#
# This code sets up a simulation with HFSS and adds a frequency sweep.

setup = c.setups.add_setup("Setup1", "1GHz")
setup = c.setups.add_setup("Setup1", "1GHz", 0.02, 10)
setup.add_sweep("Sweep1", "0.01GHz", "5GHz", "0.1GHz")

# ## Provide additional stackup settings
Expand Down
15 changes: 11 additions & 4 deletions src/pyedb/dotnet/edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ def create_edb(self):
def import_layout_pcb(
self,
input_file,
working_dir,
working_dir="",
anstranslator_full_path="",
use_ppe=False,
control_file=None,
Expand All @@ -616,7 +616,7 @@ def import_layout_pcb(
----------
input_file : str
Full path to the board file.
working_dir : str
working_dir : str, optional
Directory in which to create the ``aedb`` folder. The name given to the AEDB file
is the same as the name of the board file.
anstranslator_full_path : str, optional
Expand Down Expand Up @@ -1510,6 +1510,13 @@ def import_gds_file(
else:
return False
else:
if anstranslator_full_path and os.path.exists(anstranslator_full_path):
path = anstranslator_full_path
else:
path = os.path.join(self.base_path, "anstranslator")
if is_windows:
path += ".exe"

temp_map_file = os.path.splitext(inputGDS)[0] + ".map"
temp_layermap_file = os.path.splitext(inputGDS)[0] + ".layermap"

Expand All @@ -1529,10 +1536,10 @@ def import_gds_file(
else:
self.logger.error("Unable to define control file.")

command = [anstranslator_full_path, inputGDS, f'-g="{map_file}"', f'-c="{control_file}"']
command = [path, inputGDS, f'-g="{map_file}"', f'-c="{control_file}"']
else:
command = [
anstranslator_full_path,
path,
inputGDS,
f'-o="{control_file_temp}"' f'-t="{tech_file}"',
f'-g="{map_file}"',
Expand Down
73 changes: 60 additions & 13 deletions src/pyedb/dotnet/edb_core/edb_data/control_file.py
gkorompi marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import re
import subprocess
import sys
import xml

from pyedb.edb_logger import pyedb_logger
from pyedb.generic.general_methods import ET, env_path, env_value, is_linux
Expand Down Expand Up @@ -964,14 +965,14 @@ def _write_xml(self, root):
class ControlFileSetup:
"""Setup Class."""

def __init__(self, name):
def __init__(self, name, adapt_freq="1GHz", maxdelta=0.02, maxpasses=10):
self.name = name
self.enabled = True
self.save_fields = False
self.save_rad_fields = False
self.frequency = "1GHz"
self.maxpasses = 10
self.max_delta = 0.02
self.frequency = adapt_freq
self.maxpasses = maxpasses
self.max_delta = maxdelta
self.union_polygons = True
self.small_voids_area = 0
self.mode_type = "IC"
Expand Down Expand Up @@ -1082,22 +1083,25 @@ class ControlFileSetups:
def __init__(self):
self.setups = []

def add_setup(self, name, frequency):
def add_setup(self, name, adapt_freq, maxdelta, maxpasses):
"""Add a new setup

Parameters
----------
name : str
Setup name.
frequency : str
Setup Name.
adapt_freq : str, optional
Setup Frequency.
maxdelta : float, optional
Maximum Delta.
maxpasses : int, optional
Maximum Number of Passes.

Returns
-------
:class:`pyedb.dotnet.edb_core.edb_data.control_file.ControlFileSetup`
"""
setup = ControlFileSetup(name)
setup.frequency = frequency
setup = ControlFileSetup(name, adapt_freq, maxdelta, maxpasses)
self.setups.append(setup)
return setup

Expand All @@ -1112,17 +1116,17 @@ class ControlFile:

def __init__(self, xml_input=None, tecnhology=None, layer_map=None):
self.stackup = ControlFileStackup()
self.boundaries = ControlFileBoundaries()
self.setups = ControlFileSetups()
if xml_input:
self.parse_xml(xml_input)
if tecnhology:
self.parse_technology(tecnhology)
if layer_map:
self.parse_layer_map(layer_map)
self.boundaries = ControlFileBoundaries()
self.remove_holes = False
self.remove_holes_area_minimum = 30
self.remove_holes_units = "um"
self.setups = ControlFileSetups()
self.components = ControlFileComponents()
self.import_options = ControlFileImportOptions()
pass
Expand Down Expand Up @@ -1262,6 +1266,50 @@ def parse_xml(self, xml_input):
via.remove_unconnected = (
True if i.attrib["RemoveUnconnected"] == "true" else False
)
if el.tag == "Boundaries":
for port_el in el:
if port_el.tag == "CircuitPortPt":
self.boundaries.add_port(
name=port_el.attrib["Name"],
x1=port_el.attrib["x1"],
y1=port_el.attrib["y1"],
layer1=port_el.attrib["Layer1"],
x2=port_el.attrib["x2"],
y2=port_el.attrib["y2"],
layer2=port_el.attrib["Layer2"],
z0=port_el.attrib["Z0"],
)
setups = root.find("SimulationSetups")
if setups:
hfsssetup = setups.find("HFSSSetup")
if hfsssetup:
if "Name" in hfsssetup.attrib:
name = hfsssetup.attrib["Name"]
hfsssimset = hfsssetup.find("HFSSSimulationSettings")
if hfsssimset:
hfssadaptset = hfsssimset.find("HFSSAdaptiveSettings")
if hfssadaptset:
adaptset = hfssadaptset.find("AdaptiveSettings")
if adaptset:
singlefreqdatalist = adaptset.find("SingleFrequencyDataList")
if singlefreqdatalist:
adaptfreqdata = singlefreqdatalist.find("AdaptiveFrequencyData")
if adaptfreqdata:
if isinstance(
adaptfreqdata.find("AdaptiveFrequency"), xml.etree.ElementTree.Element
):
adapt_freq = adaptfreqdata.find("AdaptiveFrequency").text
else:
adapt_freq = "1GHz"
if isinstance(adaptfreqdata.find("MaxDelta"), xml.etree.ElementTree.Element):
maxdelta = adaptfreqdata.find("MaxDelta").text
else:
maxdelta = 0.02
if isinstance(adaptfreqdata.find("MaxPasses"), xml.etree.ElementTree.Element):
maxpasses = adaptfreqdata.find("MaxPasses").text
else:
maxpasses = 10
self.setups.add_setup(name, adapt_freq, maxdelta, maxpasses)
return True

def write_xml(self, xml_output):
Expand All @@ -1278,8 +1326,7 @@ def write_xml(self, xml_output):
"""
control = ET.Element("{http://www.ansys.com/control}Control", attrib={"schemaVersion": "1.0"})
self.stackup._write_xml(control)
if self.boundaries.ports or self.boundaries.extents:
self.boundaries._write_xml(control)
self.boundaries._write_xml(control)
if self.remove_holes:
hole = ET.SubElement(control, "RemoveHoles")
hole.set("HoleAreaMinimum", str(self.remove_holes_area_minimum))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,25 @@
</Vias>
</ELayers>
</Stackup>
<Boundaries LengthUnit="um">
<CircuitPortPt Name="P2" x1="-1770" y1="1800" Layer1="met4" x2="-1770" y2="1800" Layer2="met5" Z0="50"/>
</Boundaries>

<SimulationSetups>
<HFSSSetup schemaVersion="1.0" Name="Setup Test">
<HFSSSimulationSettings>
<HFSSAdaptiveSettings>
<AdaptiveSettings>
<SingleFrequencyDataList>
<AdaptiveFrequencyData>
<AdaptiveFrequency>0.5GHz</AdaptiveFrequency>
<MaxDelta>0.01</MaxDelta>
<MaxPasses>10</MaxPasses>
</AdaptiveFrequencyData>
</SingleFrequencyDataList>
</AdaptiveSettings>
</HFSSAdaptiveSettings>
</HFSSSimulationSettings>
</HFSSSetup>
</SimulationSetups>
</c:Control>
8 changes: 4 additions & 4 deletions tests/legacy/system/test_edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1341,7 +1341,7 @@ def test_import_gds_from_tech(self):
self.local_scratch.copyfile(gds_in, gds_out)

c = ControlFile(c_file_in, layer_map=c_map)
setup = c.setups.add_setup("Setup1", "1GHz")
setup = c.setups.add_setup("Setup1", "1GHz", 0.02, 10)
setup.add_sweep("Sweep1", "0.01GHz", "5GHz", "0.1GHz")
c.boundaries.units = "um"
c.stackup.units = "um"
Expand All @@ -1364,8 +1364,8 @@ def test_import_gds_from_tech(self):
)

assert edb
assert "P1" in edb.excitations
assert "Setup1" in edb.setups
assert "P1" and "P2" in edb.excitations
assert "Setup1" and "Setup Test" in edb.setups
assert "B1" in edb.components.instances
edb.close()

Expand Down Expand Up @@ -1495,7 +1495,7 @@ def test_add_layer_api_with_control_file(self):
)
assert ctrl.boundaries.ports
# setup using q3D for DC point
setup = ctrl.setups.add_setup("test_setup", "10GHz")
setup = ctrl.setups.add_setup("test_setup", "10GHz", 0.02, 10)
assert setup
setup.add_sweep(
name="test_sweep",
Expand Down
Loading