Rewrite of touchstone parser

- keeped compatible with previous version
- add test examples of touchstone files
- commented out writing to loaded file to fix bug #99
pull/100/head
Holger Mueller 2019-11-19 10:00:17 +01:00
rodzic d12cdd4b24
commit c3639b2557
8 zmienionych plików z 108 dodań i 20 usunięć

Wyświetl plik

@ -905,7 +905,8 @@ class NanoVNASaver(QtWidgets.QWidget):
self.data21 = []
t = Touchstone(filename)
t.load()
self.saveData(t.s11data, t.s21data, filename)
# shouldn't modify read file. even destroys it if read fails
# self.saveData(t.s11data, t.s21data, filename)
self.dataUpdated()
def sizeHint(self) -> QtCore.QSize:

Wyświetl plik

@ -16,6 +16,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
import cmath
import io
from NanoVNASaver.RFTools import Datapoint
logger = logging.getLogger(__name__)
@ -61,30 +62,73 @@ class Options:
class Touchstone:
def __init__(self, filename):
def __init__(self, filename: str):
self.filename = filename
self.s11data = []
self.s21data = []
self.s12data = []
self.s22data = []
self.sdata = [[], [], [], []] # at max 4 data pairs
self.comments = []
self.opts = Options()
@property
def s11data(self) -> list:
return self.sdata[0]
@s11data.setter
def s11data(self, data: list):
self.sdata[0] = data[:]
@property
def s21data(self) -> list:
return self.sdata[1]
@s21data.setter
def s21data(self, data: list):
self.sdata[1] = data[:]
@property
def s12data(self) -> list:
return self.sdata[2]
@s12data.setter
def s12data(self, data: list):
self.sdata[2] = data[:]
@property
def s22data(self) -> list:
return self.sdata[3]
@s22data.setter
def s22data(self, data: list):
self.sdata[3] = data[:]
def _parse_comments(self, fp) -> str:
for line in fp:
line = line.strip()
if line.startswith("!"):
logger.info(line)
self.comments.append(line)
else:
return line
def load(self):
logger.info("Attempting to open file %s", self.filename)
sdata = [[], [], [], []] # at max 4 data pairs
try:
with open(self.filename) as infile:
self.loads(infile.read())
except TypeError as e:
logger.exception("Failed to parse %s: %s", self.filename, e)
except IOError as e:
logger.exception("Failed to open %s: %s", self.filename, e)
with open(self.filename, "r") as file:
for line in file:
line = line.strip()
if line.startswith("!"):
logger.info(line)
self.comments.append(line)
continue
break
self.opts.parse(line)
def loads(self, s: str):
"""Parse touchstone 1.1 string input
appends to existing sdata if Touchstone object exists
"""
with io.StringIO(s) as file:
opts_line = self._parse_comments(file)
self.opts.parse(opts_line)
prev_freq = prev_len = 0
prev_freq = 0.0
prev_len = 0
for line in file:
# ignore empty lines (even if not specified)
if not line.strip():
@ -108,7 +152,7 @@ class Touchstone:
elif data_len != prev_len:
raise TypeError("Inconsistent number of pairs: " + line)
data_list = iter(sdata)
data_list = iter(self.sdata)
vals = iter(data)
for v in vals:
if self.opts.format == "ri":
@ -118,7 +162,5 @@ class Touchstone:
z = cmath.polar(float(v), float(next(vals)))
next(data_list).append(Datapoint(freq, z.real, z.imag))
self.s11data, self.s21data, self.s12data, self.s22data = sdata[:]
def setFilename(self, filename):
self.filename = filename

Wyświetl plik

@ -0,0 +1,9 @@
# Hz S RI R 50
140000000 -0.720544874 -0.074467673
140307234 -0.707615315 -0.045678697
140614468 -0.694235622 -0.017205553
140921702 -0.679476678 0.011064857
141228936 0.037949264
141536169 -0.645231842 0.06495472
141843404 -0.625548779 0.090901531
142150638 -0.605278372 0.116493001

Wyświetl plik

@ -0,0 +1,16 @@
! Vector Network Analyzer VNA R2
! Tucson Amateur Packet Radio
! Saturday, 9 November, 2019 17:48:47
! Frequency S11 S21 S12 S22
! ListType=Lin
# HZ S RI R 50
000500000 -3.33238E-001 1.80018E-004 6.74780E-001 -8.19510E-007 6.75290E-001 -8.20129E-007 -3.33238E-001 3.08078E-004
001382728 -3.33017E-001 6.89580E-004 6.74251E-001 -3.70855E-004 6.74761E-001 -5.04361E-004 -3.33016E-001 9.45694E-004
002265456 -3.33136E-001 1.06095E-003 6.74766E-001 -1.00228E-003 6.75276E-001 -1.00304E-003 -3.33136E-001 1.06095E-003
003148184 -3.33120E-001 1.97467E-003 6.74773E-001 -1.65230E-003 6.74773E-001 -1.65230E-003 -3.33121E-001 1.91064E-003
004030912 -3.32847E-001 2.45743E-003 6.74777E-001 -2.28839E-003 6.75288E-001 -2.15679E-003
004913640 -3.32746E-001 2.93382E-003 6.75260E-001 -2.94645E-003 6.75261E-001 -2.81312E-003 -3.32990E-001 3.06364E-003
005796368 -3.33479E-001 3.06528E-003 6.75798E-001 -2.32365E-003 6.76309E-001 -2.32540E-003 -3.33479E-001 3.06528E-003
006679097 -3.32609E-001 3.80377E-003 6.74764E-001 -4.08250E-003 6.74764E-001 -4.08250E-003 -3.32854E-001 3.80608E-003
007561825 -3.32448E-001 4.35906E-003 6.75247E-001 -4.96650E-003 6.75249E-001 -4.69986E-003 -3.32692E-001 4.36169E-003
008444553 -3.32510E-001 4.94361E-003 6.74737E-001 -5.33508E-003 6.75248E-001 -5.20579E-003 -3.32508E-001 5.13540E-003

Wyświetl plik

@ -0,0 +1,8 @@
# Hz S RI R 50
140000000 -0.720544874 -0.074467673
140307234 -0.707615315 -0.045678697
140921702 -0.679476678 0.011064857
140614468 -0.694235622 -0.017205553
141536169 -0.645231842 0.06495472
141843404 -0.625548779 0.090901531
142150638 -0.605278372 0.116493001

Wyświetl plik

@ -0,0 +1,12 @@
# Hz S RI R 50
140000000 -0.720544874 -0.074467673
140307234 -0.707615315 -0.045678697
140614468 -0.694235622 -0.017205553
140921702 -0.679476678 0.011064857
141228936 -0.662805676 0.037949264
141536169 -0.645231842 0.06495472 ! just a test comment
141843404 -0.625548779 0.090901531
142150638 -0.605278372 0.116493001
142457872 -0.583680212 0.140287563
142765106 -0.560637235 0.16401714
143072339 -0.536502182 0.186390563