kopia lustrzana https://github.com/NanoVNA-Saver/nanovna-saver
Feature/continuoussweep(#508)record_mode
commit
1a751de909
|
@ -27,8 +27,9 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class SweepMode(Enum):
|
class SweepMode(Enum):
|
||||||
SINGLE = 0
|
SINGLE = 0
|
||||||
CONTINOUS = 1
|
CONTINUOUS = 1
|
||||||
AVERAGE = 2
|
AVERAGE = 2
|
||||||
|
CONTINUOUS_FILE = 3
|
||||||
|
|
||||||
|
|
||||||
class Properties:
|
class Properties:
|
||||||
|
|
|
@ -27,6 +27,7 @@ from PyQt5.QtCore import pyqtSlot, pyqtSignal
|
||||||
from NanoVNASaver.Calibration import correct_delay
|
from NanoVNASaver.Calibration import correct_delay
|
||||||
from NanoVNASaver.RFTools import Datapoint
|
from NanoVNASaver.RFTools import Datapoint
|
||||||
from NanoVNASaver.Settings.Sweep import Sweep, SweepMode
|
from NanoVNASaver.Settings.Sweep import Sweep, SweepMode
|
||||||
|
from NanoVNASaver.Touchstone import Touchstone
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -72,6 +73,7 @@ class SweepWorker(QtCore.QRunnable):
|
||||||
self.running = False
|
self.running = False
|
||||||
self.error_message = ""
|
self.error_message = ""
|
||||||
self.offsetDelay = 0
|
self.offsetDelay = 0
|
||||||
|
self.sdata = [[], [], [], []]
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
|
@ -94,6 +96,12 @@ class SweepWorker(QtCore.QRunnable):
|
||||||
self.running = True
|
self.running = True
|
||||||
self.percentage = 0
|
self.percentage = 0
|
||||||
|
|
||||||
|
# open file to sweep continuously and write all result in the file
|
||||||
|
with open("s1p_continuous.s1p", "w") as fileConS1:
|
||||||
|
fileConS1.write("# HZ S RI R 50 \n")
|
||||||
|
with open("s2p_continuous.s2p", "w") as fileConS2:
|
||||||
|
fileConS2.write("# HZ S RI R 50 \n")
|
||||||
|
|
||||||
with self.app.sweep.lock:
|
with self.app.sweep.lock:
|
||||||
sweep = self.app.sweep.copy()
|
sweep = self.app.sweep.copy()
|
||||||
|
|
||||||
|
@ -117,25 +125,48 @@ class SweepWorker(QtCore.QRunnable):
|
||||||
|
|
||||||
def _run_loop(self) -> None:
|
def _run_loop(self) -> None:
|
||||||
sweep = self.sweep
|
sweep = self.sweep
|
||||||
|
j = 0
|
||||||
averages = (sweep.properties.averages[0]
|
averages = (sweep.properties.averages[0]
|
||||||
if sweep.properties.mode == SweepMode.AVERAGE
|
if sweep.properties.mode == SweepMode.AVERAGE
|
||||||
else 1)
|
else 1)
|
||||||
logger.info("%d averages", averages)
|
logger.info("%d averages", averages)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
max_sweep = 0
|
||||||
for i in range(sweep.segments):
|
for i in range(sweep.segments):
|
||||||
logger.debug("Sweep segment no %d", i)
|
logger.debug("Sweep segment no %d", i)
|
||||||
if self.stopped:
|
if self.stopped:
|
||||||
logger.debug("Stopping sweeping as signalled")
|
logger.debug("Stopping sweeping as signalled")
|
||||||
break
|
break
|
||||||
start, stop = sweep.get_index_range(i)
|
start, stop = sweep.get_index_range(i)
|
||||||
|
try:
|
||||||
freq, values11, values21 = self.readAveragedSegment(
|
logger.debug("Single mode ...")
|
||||||
start, stop, averages)
|
freq, values11, values21 = self.readAveragedSegment(
|
||||||
self.percentage = (i + 1) * 100 / sweep.segments
|
start, stop, averages)
|
||||||
self.updateData(freq, values11, values21, i)
|
self.percentage = (i + 1) * 100 / sweep.segments
|
||||||
if sweep.properties.mode != SweepMode.CONTINOUS:
|
self.updateData(freq, values11, values21, i)
|
||||||
break
|
except ValueError as e:
|
||||||
|
self.gui_error(str(e))
|
||||||
|
else:
|
||||||
|
if sweep.properties.mode == SweepMode.CONTINUOUS_FILE:
|
||||||
|
logger.debug("Continuous infile mode ...")
|
||||||
|
try:
|
||||||
|
if self.stopped:
|
||||||
|
logger.debug("Stopping sweeping as signalled")
|
||||||
|
break
|
||||||
|
freq, values11, values21 = self.readAveragedSegment(
|
||||||
|
start, stop, averages)
|
||||||
|
max_sweep = max_sweep + 1
|
||||||
|
self.percentage = j + 1 # (i + 1) * 100 / sweep.segments
|
||||||
|
self.updateDataContinuouse(freq, values11, values21, j)
|
||||||
|
if max_sweep >= 100:
|
||||||
|
sweep.properties.mode = SweepMode.SINGLE
|
||||||
|
except ValueError as e:
|
||||||
|
self.gui_error(str(e))
|
||||||
|
continue
|
||||||
|
if sweep.properties.mode == SweepMode.CONTINUOUS:
|
||||||
|
logger.debug("Continuous mode ...")
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
|
||||||
def init_data(self):
|
def init_data(self):
|
||||||
self.data11 = []
|
self.data11 = []
|
||||||
|
@ -175,6 +206,59 @@ class SweepWorker(QtCore.QRunnable):
|
||||||
logger.debug('Sending "updated" signal')
|
logger.debug('Sending "updated" signal')
|
||||||
self.signals.updated.emit()
|
self.signals.updated.emit()
|
||||||
|
|
||||||
|
|
||||||
|
def updateDataContinuouse(self, frequencies, values11, values21, index):
|
||||||
|
# Update the data from (i*101) to (i+1)*101
|
||||||
|
logger.debug(
|
||||||
|
"Calculating data and inserting in existing data at index %d",
|
||||||
|
index)
|
||||||
|
offset = self.sweep.points * index
|
||||||
|
|
||||||
|
raw_data11 = [Datapoint(freq, values11[i][0], values11[i][1])
|
||||||
|
for i, freq in enumerate(frequencies)]
|
||||||
|
raw_data21 = [Datapoint(freq, values21[i][0], values21[i][1])
|
||||||
|
for i, freq in enumerate(frequencies)]
|
||||||
|
|
||||||
|
data11, data21 = self.applyCalibration(raw_data11, raw_data21)
|
||||||
|
logger.debug("update Freqs: %s, Offset: %s", len(frequencies), offset)
|
||||||
|
for i in range(len(frequencies)):
|
||||||
|
self.data11[offset + i] = data11[i]
|
||||||
|
self.data21[offset + i] = data21[i]
|
||||||
|
self.rawData11[offset + i] = raw_data11[i]
|
||||||
|
self.rawData21[offset + i] = raw_data21[i]
|
||||||
|
|
||||||
|
logger.debug("Saving data to application (%d and %d points)",
|
||||||
|
len(self.data11), len(self.data21))
|
||||||
|
self.app.saveData(self.data11, self.data21)
|
||||||
|
logger.debug('Sending "updated" signal')
|
||||||
|
if self.app.sweep.properties.mode == SweepMode.CONTINUOUS_FILE:
|
||||||
|
ts = Touchstone("s2p_continuous.s2p")
|
||||||
|
ts.sdata[0] = self.data11
|
||||||
|
nr_params = 4
|
||||||
|
if nr_params > 1:
|
||||||
|
ts.sdata[1] = self.data21
|
||||||
|
for dp in self.data11:
|
||||||
|
ts.sdata[2].append(Datapoint(dp.freq, 0, 0))
|
||||||
|
ts.sdata[3].append(Datapoint(dp.freq, 0, 0))
|
||||||
|
with open("s1p_continuous.s1p", "a") as fileConS1:
|
||||||
|
for i in range(len(self.data11)):
|
||||||
|
freq, re, im = self.data11[i]
|
||||||
|
line = str(freq) + " " + str(re) + " " + str(im)
|
||||||
|
fileConS1.write(line)
|
||||||
|
fileConS1.write("\n")
|
||||||
|
with open("s2p_continuous.s2p", "a") as fileConS2:
|
||||||
|
for i in range(len(self.data11)):
|
||||||
|
freq, re, im = self.data11[i]
|
||||||
|
line = str(freq) + " " + str(re) + " " + str(im)
|
||||||
|
for j in range(1, nr_params):
|
||||||
|
dp = ts.sdata[j][i]
|
||||||
|
if dp.freq != self.data11[i][0]:
|
||||||
|
raise LookupError("Frequencies of sdata not correlated")
|
||||||
|
line += f" {dp.re} {dp.im}"
|
||||||
|
line += "\n"
|
||||||
|
fileConS2.write(line)
|
||||||
|
self.signals.updated.emit()
|
||||||
|
|
||||||
def applyCalibration(self,
|
def applyCalibration(self,
|
||||||
raw_data11: List[Datapoint],
|
raw_data11: List[Datapoint],
|
||||||
raw_data21: List[Datapoint]
|
raw_data21: List[Datapoint]
|
||||||
|
@ -236,7 +320,7 @@ class SweepWorker(QtCore.QRunnable):
|
||||||
self.signals.updated.emit()
|
self.signals.updated.emit()
|
||||||
|
|
||||||
if not values11:
|
if not values11:
|
||||||
raise IOError("Invalid data during swwep")
|
raise IOError("Invalid data during sweep")
|
||||||
|
|
||||||
truncates = self.sweep.properties.averages[1]
|
truncates = self.sweep.properties.averages[1]
|
||||||
if truncates > 0 and averages > 1:
|
if truncates > 0 and averages > 1:
|
||||||
|
|
|
@ -683,7 +683,7 @@ class CalibrationWindow(QtWidgets.QWidget):
|
||||||
self.btn_automatic.setDisabled(False)
|
self.btn_automatic.setDisabled(False)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.app.sweep.properties.mode == SweepMode.CONTINOUS:
|
if self.app.sweep.properties.mode == SweepMode.CONTINUOUS:
|
||||||
QtWidgets.QMessageBox(
|
QtWidgets.QMessageBox(
|
||||||
QtWidgets.QMessageBox.Information,
|
QtWidgets.QMessageBox.Information,
|
||||||
"Continuous sweep enabled",
|
"Continuous sweep enabled",
|
||||||
|
|
|
@ -77,12 +77,12 @@ class SweepSettingsWindow(QtWidgets.QWidget):
|
||||||
lambda: self.update_mode(SweepMode.SINGLE))
|
lambda: self.update_mode(SweepMode.SINGLE))
|
||||||
sweep_btn_layout.addWidget(radio_button)
|
sweep_btn_layout.addWidget(radio_button)
|
||||||
|
|
||||||
radio_button = QtWidgets.QRadioButton("Continous sweep")
|
radio_button = QtWidgets.QRadioButton("Continuous sweep")
|
||||||
radio_button.setMinimumHeight(20)
|
radio_button.setMinimumHeight(20)
|
||||||
radio_button.setChecked(
|
radio_button.setChecked(
|
||||||
self.app.sweep.properties.mode == SweepMode.CONTINOUS)
|
self.app.sweep.properties.mode == SweepMode.CONTINUOUS)
|
||||||
radio_button.clicked.connect(
|
radio_button.clicked.connect(
|
||||||
lambda: self.update_mode(SweepMode.CONTINOUS))
|
lambda: self.update_mode(SweepMode.CONTINUOUS))
|
||||||
sweep_btn_layout.addWidget(radio_button)
|
sweep_btn_layout.addWidget(radio_button)
|
||||||
|
|
||||||
radio_button = QtWidgets.QRadioButton("Averaged sweep")
|
radio_button = QtWidgets.QRadioButton("Averaged sweep")
|
||||||
|
@ -93,6 +93,15 @@ class SweepSettingsWindow(QtWidgets.QWidget):
|
||||||
lambda: self.update_mode(SweepMode.AVERAGE))
|
lambda: self.update_mode(SweepMode.AVERAGE))
|
||||||
sweep_btn_layout.addWidget(radio_button)
|
sweep_btn_layout.addWidget(radio_button)
|
||||||
|
|
||||||
|
radio_button = QtWidgets.QRadioButton("Continuous sweep infile")
|
||||||
|
radio_button.setMinimumHeight(20)
|
||||||
|
radio_button.setChecked(
|
||||||
|
self.app.sweep.properties.mode == SweepMode.CONTINUOUS_FILE)
|
||||||
|
radio_button.clicked.connect(
|
||||||
|
lambda: self.update_mode(SweepMode.CONTINUOUS_FILE))
|
||||||
|
sweep_btn_layout.addWidget(radio_button)
|
||||||
|
|
||||||
|
|
||||||
layout.addRow(sweep_btn_layout)
|
layout.addRow(sweep_btn_layout)
|
||||||
|
|
||||||
# Log sweep
|
# Log sweep
|
||||||
|
|
Ładowanie…
Reference in New Issue