Skip to content

Commit 2dcd6f5

Browse files
hfss fixes for export_touchstone() (#1166)
* hfss fixes to export touchstone * fixes in input name variations * fix variations dict in hfss, hfss3d and circuit * Fix, update export_touchstone() and update tests * Update pyaedt/application/Analysis.py Co-authored-by: Massimo Capodiferro <[email protected]> Co-authored-by: Massimo Capodiferro <[email protected]>
1 parent 284fa4a commit 2dcd6f5

File tree

7 files changed

+198
-177
lines changed

7 files changed

+198
-177
lines changed

_unittest/test_12_PostProcessing.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,26 @@ def test_03_get_solution_data(self):
147147
assert os.path.exists(os.path.join(self.local_scratch.path, "output.csv"))
148148

149149
def test_04_export_touchstone(self):
150-
self.aedtapp.export_touchstone("Setup1", "Sweep", os.path.join(self.local_scratch.path, "Setup1_Sweep.S2p"))
150+
setup_name = "Setup1"
151+
sweep_name = "Sweep"
152+
self.aedtapp.export_touchstone(
153+
setup_name, sweep_name, os.path.join(self.local_scratch.path, "Setup1_Sweep.S2p")
154+
)
151155
assert os.path.exists(os.path.join(self.local_scratch.path, "Setup1_Sweep.S2p"))
152156

157+
sweep_name = None
158+
self.aedtapp.export_touchstone(
159+
setup_name, sweep_name, os.path.join(self.local_scratch.path, "Setup1_Sweep2.S2p")
160+
)
161+
assert os.path.exists(os.path.join(self.local_scratch.path, "Setup1_Sweep2.S2p"))
162+
setup_name = None
163+
self.aedtapp.export_touchstone(
164+
setup_name, sweep_name, os.path.join(self.local_scratch.path, "Setup1_Sweep3.S2p")
165+
)
166+
assert os.path.exists(os.path.join(self.local_scratch.path, "Setup1_Sweep3.S2p"))
167+
168+
assert self.aedtapp.export_touchstone(setup_name, sweep_name)
169+
153170
@pytest.mark.skipif(config["build_machine"] == True, reason="Not running in non-graphical mode")
154171
def test_05_export_report_to_jpg(self):
155172

_unittest/test_21_Circuit.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,14 @@ def test_17_create_setup(self):
203203
def test_18_export_touchstone(self):
204204
assert self.aedtapp.analyze_nominal()
205205
time.sleep(30)
206-
assert self.aedtapp.export_touchstone("Dom_LNA", "Dom_LNA", os.path.join(self.local_scratch.path, "new.s2p"))
206+
solution_name = "Dom_LNA"
207+
sweep_name = None
208+
file_name = os.path.join(self.local_scratch.path, "new.s2p")
209+
assert self.aedtapp.export_touchstone(solution_name, sweep_name, file_name)
210+
assert os.path.exists(file_name)
211+
assert self.aedtapp.existing_analysis_sweeps[0] == solution_name
212+
assert self.aedtapp.setup_names[0] == solution_name
213+
assert self.aedtapp.export_touchstone(solution_name, sweep_name)
207214

208215
def test_19A_create_sweeps(self):
209216
setup_name = "Sweep_LNA"

_unittest/test_41_3dlayout_modeler.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,13 @@ def test_19B_analyze_setup(self):
364364
@pytest.mark.skipif(os.name == "posix", reason="To be investigated on linux.")
365365
def test_19C_export_touchsthone(self):
366366
filename = os.path.join(scratch_path, "touchstone.s2p")
367-
assert self.aedtapp.export_touchstone("RFBoardSetup3", "Last Adaptive", filename, [], [])
367+
solution_name = "RFBoardSetup3"
368+
sweep_name = "Last Adaptive"
369+
assert self.aedtapp.export_touchstone(solution_name, sweep_name, filename)
368370
assert os.path.exists(filename)
371+
assert self.aedtapp.export_touchstone(solution_name)
372+
sweep_name = None
373+
assert self.aedtapp.export_touchstone(solution_name, sweep_name)
369374

370375
def test_19D_export_to_hfss(self):
371376
with Scratch(scratch_path) as local_scratch:

pyaedt/application/Analysis.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,3 +1709,120 @@ def submit_job(
17091709
f1.write(line)
17101710
f1.close()
17111711
return self.odesktop.SubmitJob(os.path.join(project_path, "Job_settings.areg"), project_file)
1712+
1713+
@pyaedt_function_handler()
1714+
def _export_touchstone(
1715+
self, solution_name=None, sweep_name=None, file_name=None, variations=None, variations_value=None
1716+
):
1717+
"""Export the Touchstone file to a local folder.
1718+
1719+
Parameters
1720+
----------
1721+
solution_name : str, optional
1722+
Name of the solution that has been solved.
1723+
sweep_name : str, optional
1724+
Name of the sweep that has been solved.
1725+
This parameter has to be ignored or set with same value as solution_name
1726+
file_name : str, optional
1727+
Full path and name for the Touchstone file. The default is ``None``,
1728+
which exports the file to the working directory.
1729+
variations : list, optional
1730+
List of all parameter variations. For example, ``["$AmbientTemp", "$PowerIn"]``.
1731+
The default is ``None``.
1732+
variations_value : list, optional
1733+
List of all parameter variation values. For example, ``["22cel", "100"]``.
1734+
The default is ``None``.
1735+
1736+
Returns
1737+
-------
1738+
bool
1739+
``True`` when successful, ``False`` when failed.
1740+
"""
1741+
if variations is None:
1742+
variations = list(self.available_variations.nominal_w_values_dict.keys())
1743+
if variations_value is None:
1744+
variations_value = [str(x) for x in list(self.available_variations.nominal_w_values_dict.values())]
1745+
1746+
if solution_name is None:
1747+
nominal_sweep_list = [x.strip() for x in self.nominal_sweep.split(":")]
1748+
solution_name = nominal_sweep_list[0]
1749+
if self.design_type == "Circuit Design":
1750+
sweep_name = solution_name
1751+
else:
1752+
if sweep_name is None:
1753+
for sol in self.existing_analysis_sweeps:
1754+
if solution_name == sol.split(":")[0].strip():
1755+
sweep_name = sol.split(":")[1].strip()
1756+
break
1757+
1758+
if self.design_type == "HFSS 3D Layout Design":
1759+
n = str(len(self.port_list))
1760+
else:
1761+
n = str(len(self.excitations))
1762+
# Normalize the save path
1763+
if not file_name:
1764+
appendix = ""
1765+
for v, vv in zip(variations, variations_value):
1766+
appendix += "_" + v + vv.replace("'", "")
1767+
ext = ".S" + n + "p"
1768+
filename = os.path.join(self.working_directory, solution_name + "_" + sweep_name + appendix + ext)
1769+
else:
1770+
filename = file_name.replace("//", "/").replace("\\", "/")
1771+
self.logger.info("Exporting Touchstone " + filename)
1772+
DesignVariations = ""
1773+
for i in range(len(variations)):
1774+
DesignVariations += str(variations[i]) + "='" + str(variations_value[i].replace("'", "")) + "' "
1775+
# DesignVariations = "$AmbientTemp=\'22cel\' $PowerIn=\'100\'"
1776+
# array containing "SetupName:SolutionName" pairs (note that setup and solution are separated by a colon)
1777+
SolutionSelectionArray = [solution_name + ":" + sweep_name]
1778+
# 2=tab delimited spreadsheet (.tab), 3= touchstone (.sNp), 4= CitiFile (.cit),
1779+
# 7=Matlab (.m), 8=Terminal Z0 spreadsheet
1780+
FileFormat = 3
1781+
OutFile = filename # full path of output file
1782+
# array containin the frequencies to export, use ["all"] for all frequencies
1783+
FreqsArray = ["all"]
1784+
DoRenorm = True # perform renormalization before export
1785+
RenormImped = 50 # Real impedance value in ohm, for renormalization
1786+
DataType = "S" # Type: "S", "Y", or "Z" matrix to export
1787+
Pass = -1 # The pass to export. -1 = export all passes.
1788+
ComplexFormat = 0 # 0=Magnitude/Phase, 1=Real/Immaginary, 2=dB/Phase
1789+
DigitsPrecision = 15 # Touchstone number of digits precision
1790+
IncludeGammaImpedance = True # Include Gamma and Impedance in comments
1791+
NonStandardExtensions = False # Support for non-standard Touchstone extensions
1792+
1793+
if self.design_type == "HFSS":
1794+
self.osolution.ExportNetworkData(
1795+
DesignVariations,
1796+
SolutionSelectionArray,
1797+
FileFormat,
1798+
OutFile,
1799+
FreqsArray,
1800+
DoRenorm,
1801+
RenormImped,
1802+
DataType,
1803+
Pass,
1804+
ComplexFormat,
1805+
DigitsPrecision,
1806+
False,
1807+
IncludeGammaImpedance,
1808+
NonStandardExtensions,
1809+
)
1810+
else:
1811+
self.odesign.ExportNetworkData(
1812+
DesignVariations,
1813+
SolutionSelectionArray,
1814+
FileFormat,
1815+
OutFile,
1816+
FreqsArray,
1817+
DoRenorm,
1818+
RenormImped,
1819+
DataType,
1820+
Pass,
1821+
ComplexFormat,
1822+
DigitsPrecision,
1823+
False,
1824+
IncludeGammaImpedance,
1825+
NonStandardExtensions,
1826+
)
1827+
self.logger.info("Touchstone correctly exported to %s", filename)
1828+
return True

pyaedt/circuit.py

Lines changed: 15 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -762,19 +762,21 @@ def import_touchstone_solution(self, filename, solution_name="Imported_Data"):
762762
return portnames
763763

764764
@pyaedt_function_handler()
765-
def export_touchstone(self, solutionname, sweepname, filename=None, variation=None, variations_value=None):
765+
def export_touchstone(
766+
self, solution_name=None, sweep_name=None, file_name=None, variations=None, variations_value=None
767+
):
766768
"""Export the Touchstone file to a local folder.
767769
768770
Parameters
769771
----------
770-
solutionname : str
772+
solution_name : str, optional
771773
Name of the solution that has been solved.
772-
sweepname : str
774+
sweep_name : str, optional
773775
Name of the sweep that has been solved.
774-
filename : str, optional
775-
Full path and name for the Touchstone file. The default is ``None``,
776-
which exports the file to the working directory.
777-
variation : list, optional
776+
file_name : str, optional
777+
Full path and name for the Touchstone file.
778+
The default is ``None``, in which case the file is exported to the working directory.
779+
variations : list, optional
778780
List of all parameter variations. For example, ``["$AmbientTemp", "$PowerIn"]``.
779781
The default is ``None``.
780782
variations_value : list, optional
@@ -791,62 +793,13 @@ def export_touchstone(self, solutionname, sweepname, filename=None, variation=No
791793
792794
>>> oDesign.ExportNetworkData
793795
"""
794-
if variation == None:
795-
variation = []
796-
if variations_value == None:
797-
variations_value = []
798-
799-
# Normalize the save path
800-
if not filename:
801-
appendix = ""
802-
for v, vv in zip(variation, variations_value):
803-
appendix += "_" + v + vv.replace("'", "")
804-
ext = ".S" + str(self.oboundary.GetNumExcitations()) + "p"
805-
filename = os.path.join(self.working_directory, solutionname + "_" + sweepname + appendix + ext)
806-
else:
807-
filename = filename.replace("//", "/").replace("\\", "/")
808-
self.logger.info("Exporting Touchstone " + filename)
809-
DesignVariations = ""
810-
i = 0
811-
for el in variation:
812-
DesignVariations += str(variation[i]) + "='" + str(variations_value[i].replace("'", "")) + "' "
813-
i += 1
814-
# DesignVariations = "$AmbientTemp=\'22cel\' $PowerIn=\'100\'"
815-
# array containing "SetupName:SolutionName" pairs (note that setup and solution are separated by a colon)
816-
SolutionSelectionArray = [solutionname + ":" + sweepname]
817-
# 2=tab delimited spreadsheet (.tab), 3= touchstone (.sNp), 4= CitiFile (.cit),
818-
# 7=Matlab (.m), 8=Terminal Z0 spreadsheet
819-
FileFormat = 3
820-
OutFile = filename # full path of output file
821-
# array containin the frequencies to export, use ["all"] for all frequencies
822-
FreqsArray = ["all"]
823-
DoRenorm = True # perform renormalization before export
824-
RenormImped = 50 # Real impedance value in ohm, for renormalization
825-
DataType = "S" # Type: "S", "Y", or "Z" matrix to export
826-
Pass = -1 # The pass to export. -1 = export all passes.
827-
ComplexFormat = 0 # 0=Magnitude/Phase, 1=Real/Immaginary, 2=dB/Phase
828-
DigitsPrecision = 15 # Touchstone number of digits precision
829-
IncludeGammaImpedance = True # Include Gamma and Impedance in comments
830-
NonStandardExtensions = False # Support for non-standard Touchstone extensions
831-
832-
self.odesign.ExportNetworkData(
833-
DesignVariations,
834-
SolutionSelectionArray,
835-
FileFormat,
836-
OutFile,
837-
FreqsArray,
838-
DoRenorm,
839-
RenormImped,
840-
DataType,
841-
Pass,
842-
ComplexFormat,
843-
DigitsPrecision,
844-
False,
845-
IncludeGammaImpedance,
846-
NonStandardExtensions,
796+
return self._export_touchstone(
797+
solution_name=solution_name,
798+
sweep_name=sweep_name,
799+
file_name=file_name,
800+
variations=variations,
801+
variations_value=variations_value,
847802
)
848-
self.logger.info("Touchstone correctly exported to %s", filename)
849-
return True
850803

851804
@pyaedt_function_handler()
852805
def export_fullwave_spice(

pyaedt/hfss.py

Lines changed: 16 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4171,81 +4171,39 @@ def create_qfactor_report(self, project_dir, outputlist, setupname, plotname, Xa
41714171
return True
41724172

41734173
@pyaedt_function_handler()
4174-
def export_touchstone(self, solutionname, sweepname, filename=None, variation=[], variations_value=[]):
4174+
def export_touchstone(
4175+
self, solution_name=None, sweep_name=None, file_name=None, variations=None, variations_value=None
4176+
):
41754177
"""Export the Touchstone file to a local folder.
41764178
41774179
Parameters
41784180
----------
4179-
solutionname : str
4181+
solution_name : str, optional
41804182
Name of the solution that has been solved.
4181-
sweepname : str
4183+
sweep_name : str, optional
41824184
Name of the sweep that has been solved.
4183-
filename : str, optional
4184-
Full path and name for the output file.
4185+
file_name : str, optional
4186+
Full path and name for the Touchstone file.
41854187
The default is ``None``, in which case the file is exported to the working directory.
4186-
variation : list, optional
4188+
variations : list, optional
41874189
List of all parameter variations. For example, ``["$AmbientTemp", "$PowerIn"]``.
4188-
The default is ``[]``.
4190+
The default is ``None``.
41894191
variations_value : list, optional
41904192
List of all parameter variation values. For example, ``["22cel", "100"]``.
4191-
The default is ``[]``.
4193+
The default is ``None``.
41924194
41934195
Returns
41944196
-------
41954197
bool
41964198
``True`` when successful, ``False`` when failed.
41974199
"""
4198-
4199-
# Normalize the save path
4200-
if not filename:
4201-
appendix = ""
4202-
for v, vv in zip(variation, variations_value):
4203-
appendix += "_" + v + vv.replace("'", "")
4204-
ext = ".S" + str(self.oboundary.GetNumExcitations()) + "p"
4205-
filename = os.path.join(self.working_directory, solutionname + "_" + sweepname + appendix + ext)
4206-
else:
4207-
filename = filename.replace("//", "/").replace("\\", "/")
4208-
print("Exporting Touchstone " + filename)
4209-
DesignVariations = ""
4210-
i = 0
4211-
for el in variation:
4212-
DesignVariations += str(variation[i]) + "='" + str(variations_value[i].replace("'", "")) + "' "
4213-
i += 1
4214-
# DesignVariations = "$AmbientTemp=\'22cel\' $PowerIn=\'100\'"
4215-
# array containing "SetupName:SolutionName" pairs (note that setup and solution are separated by a colon)
4216-
SolutionSelectionArray = [solutionname + ":" + sweepname]
4217-
# 2=tab delimited spreadsheet (.tab), 3= touchstone (.sNp), 4= CitiFile (.cit),
4218-
# 7=Matlab (.m), 8=Terminal Z0 spreadsheet
4219-
FileFormat = 3
4220-
OutFile = filename # full path of output file
4221-
# array containin the frequencies to export, use ["all"] for all frequencies
4222-
FreqsArray = ["all"]
4223-
DoRenorm = True # perform renormalization before export
4224-
RenormImped = 50 # Real impedance value in ohm, for renormalization
4225-
DataType = "S" # Type: "S", "Y", or "Z" matrix to export
4226-
Pass = -1 # The pass to export. -1 = export all passes.
4227-
ComplexFormat = 0 # 0=Magnitude/Phase, 1=Real/Immaginary, 2=dB/Phase
4228-
DigitsPrecision = 15 # Touchstone number of digits precision
4229-
IncludeGammaImpedance = True # Include Gamma and Impedance in comments
4230-
NonStandardExtensions = False # Support for non-standard Touchstone extensions
4231-
4232-
self.osolution.ExportNetworkData(
4233-
DesignVariations,
4234-
SolutionSelectionArray,
4235-
FileFormat,
4236-
OutFile,
4237-
FreqsArray,
4238-
DoRenorm,
4239-
RenormImped,
4240-
DataType,
4241-
Pass,
4242-
ComplexFormat,
4243-
DigitsPrecision,
4244-
False,
4245-
IncludeGammaImpedance,
4246-
NonStandardExtensions,
4200+
return self._export_touchstone(
4201+
solution_name=solution_name,
4202+
sweep_name=sweep_name,
4203+
file_name=file_name,
4204+
variations=variations,
4205+
variations_value=variations_value,
42474206
)
4248-
return True
42494207

42504208
@pyaedt_function_handler()
42514209
def set_export_touchstone(self, activate, export_dir=""):

0 commit comments

Comments
 (0)