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

passivity causality check #4319

Merged
merged 19 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions _unittest/test_44_TouchstoneParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,14 @@ def test_02_read_ts_file(self):

assert ts1.plot_insertion_losses(plot=False)
assert ts1.get_worst_curve(curve_list=ts1.get_return_loss_index(), plot=False)

def test_03_check_touchstone_file(self):
from pyaedt.generic.touchstone_parser import check_touchstone_files

check = check_touchstone_files(folder=test_T44_dir)
assert check
for k, v in check.items():
if v[0] == "passivity":
assert v[1]
elif v[0] == "causality":
assert not v[1]
76 changes: 76 additions & 0 deletions pyaedt/generic/touchstone_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import itertools
import os
import re
import subprocess

from pyaedt import is_ironpython
from pyaedt.misc.misc import installed_versions

if not is_ironpython:
import matplotlib.pyplot as plt
Expand Down Expand Up @@ -475,3 +477,77 @@ def read_touchstone(file_path):
"""
data = TouchstoneData(touchstone_file=file_path)
return data


@pyaedt_function_handler()
def check_touchstone_files(folder="", passivity=True, causality=True):
"""Check passivity and causality for all Touchstone files included in the folder.

Parameters
----------
folder : str
Folder path. The default is ``""``.
passivity : bool, optional
Whether the passivity check is enabled, The default is ``True``.
causality : bool, optional
Whether the causality check is enabled. The default is ``True``.

Returns
----------
dict
Dictionary with the SNP file name as the key and a list if the passivity and/or causality checks are enabled.
The first element in the list is a str with ``"passivity"`` or ``"causality"`` as a value. The second element
is a Boolean that is set to ``True`` when the criteria passed or ``False`` otherwise. The last element
is a string with the log information.

"""
out = {}
if not os.path.exists(folder):
return out
aedt_install_folder = list(installed_versions().values())[0]
pat_snp = re.compile("\.s\d+p$")
sNpFiles = {f: os.path.join(folder, f) for f in os.listdir(folder) if re.search(pat_snp, f)}
pat_ts = re.compile("\.ts$")
for f in os.listdir(folder):
if re.search(pat_ts, f):
sNpFiles[f] = os.path.join(folder, f)
if sNpFiles == {}:
return out
for snpf in sNpFiles:
out[snpf] = []
if os.name == "nt":
genequiv_path = os.path.join(aedt_install_folder, "genequiv.exe")
else:
genequiv_path = os.path.join(aedt_install_folder, "genequiv")
cmd = [genequiv_path]
if passivity:
cmd.append("-checkpassivity")
if causality:
cmd.append("-checkcausality")
cmd.append(sNpFiles[snpf])
output_str = str(subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0])
output_lst = output_str.split("\\r\\n")
if len(output_lst) == 1:
output_lst = output_str.splitlines()
for line in output_lst:
if "Input data" in line and passivity:
msg_log = line[17:]
is_passive = True
if "non-passive" in msg_log:
is_passive = False
out[snpf].append(["passivity", is_passive, msg_log])
if "Maximum causality" in line and causality:
msg_log = line[17:]
is_causal = True
try:
causality_check = float(msg_log.split("Maximum causality error: ")[-1].split("for entry")[0])
if not causality_check == 0.0:
is_causal = False
except:
is_causal = False
raise Exception("Failed evaluating causality value")
out[snpf].append(["causality", is_causal, msg_log])
if "Causality check is inconclusive" in line and causality:
is_causal = False
out[snpf].append(["causality", is_causal, line[17:]])
return out