diff --git a/NanoVNASaver/Settings/Sweep.py b/NanoVNASaver/Settings/Sweep.py index fa4900c..73cdf16 100644 --- a/NanoVNASaver/Settings/Sweep.py +++ b/NanoVNASaver/Settings/Sweep.py @@ -27,8 +27,9 @@ logger = logging.getLogger(__name__) class SweepMode(Enum): SINGLE = 0 - CONTINOUS = 1 + CONTINUOUS = 1 AVERAGE = 2 + CONTINUOUS_FILE = 3 class Properties: diff --git a/NanoVNASaver/SweepWorker.py b/NanoVNASaver/SweepWorker.py index d43e346..cbab532 100644 --- a/NanoVNASaver/SweepWorker.py +++ b/NanoVNASaver/SweepWorker.py @@ -27,6 +27,7 @@ from PyQt5.QtCore import pyqtSlot, pyqtSignal from NanoVNASaver.Calibration import correct_delay from NanoVNASaver.RFTools import Datapoint from NanoVNASaver.Settings.Sweep import Sweep, SweepMode +from NanoVNASaver.Touchstone import Touchstone logger = logging.getLogger(__name__) @@ -72,6 +73,7 @@ class SweepWorker(QtCore.QRunnable): self.running = False self.error_message = "" self.offsetDelay = 0 + self.sdata = [[], [], [], []] @pyqtSlot() def run(self) -> None: @@ -94,6 +96,12 @@ class SweepWorker(QtCore.QRunnable): self.running = True 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: sweep = self.app.sweep.copy() @@ -117,25 +125,48 @@ class SweepWorker(QtCore.QRunnable): def _run_loop(self) -> None: sweep = self.sweep + j = 0 averages = (sweep.properties.averages[0] if sweep.properties.mode == SweepMode.AVERAGE else 1) logger.info("%d averages", averages) - while True: + max_sweep = 0 for i in range(sweep.segments): logger.debug("Sweep segment no %d", i) if self.stopped: logger.debug("Stopping sweeping as signalled") break start, stop = sweep.get_index_range(i) - - freq, values11, values21 = self.readAveragedSegment( - start, stop, averages) - self.percentage = (i + 1) * 100 / sweep.segments - self.updateData(freq, values11, values21, i) - if sweep.properties.mode != SweepMode.CONTINOUS: - break + try: + logger.debug("Single mode ...") + freq, values11, values21 = self.readAveragedSegment( + start, stop, averages) + self.percentage = (i + 1) * 100 / sweep.segments + self.updateData(freq, values11, values21, i) + 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): self.data11 = [] @@ -175,6 +206,59 @@ class SweepWorker(QtCore.QRunnable): logger.debug('Sending "updated" signal') 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, raw_data11: List[Datapoint], raw_data21: List[Datapoint] @@ -236,7 +320,7 @@ class SweepWorker(QtCore.QRunnable): self.signals.updated.emit() if not values11: - raise IOError("Invalid data during swwep") + raise IOError("Invalid data during sweep") truncates = self.sweep.properties.averages[1] if truncates > 0 and averages > 1: diff --git a/NanoVNASaver/Windows/CalibrationSettings.py b/NanoVNASaver/Windows/CalibrationSettings.py index a2a8568..9353d88 100644 --- a/NanoVNASaver/Windows/CalibrationSettings.py +++ b/NanoVNASaver/Windows/CalibrationSettings.py @@ -683,7 +683,7 @@ class CalibrationWindow(QtWidgets.QWidget): self.btn_automatic.setDisabled(False) return - if self.app.sweep.properties.mode == SweepMode.CONTINOUS: + if self.app.sweep.properties.mode == SweepMode.CONTINUOUS: QtWidgets.QMessageBox( QtWidgets.QMessageBox.Information, "Continuous sweep enabled", diff --git a/NanoVNASaver/Windows/SweepSettings.py b/NanoVNASaver/Windows/SweepSettings.py index 633af16..82eb41b 100644 --- a/NanoVNASaver/Windows/SweepSettings.py +++ b/NanoVNASaver/Windows/SweepSettings.py @@ -77,12 +77,12 @@ class SweepSettingsWindow(QtWidgets.QWidget): lambda: self.update_mode(SweepMode.SINGLE)) sweep_btn_layout.addWidget(radio_button) - radio_button = QtWidgets.QRadioButton("Continous sweep") + radio_button = QtWidgets.QRadioButton("Continuous sweep") radio_button.setMinimumHeight(20) radio_button.setChecked( - self.app.sweep.properties.mode == SweepMode.CONTINOUS) + self.app.sweep.properties.mode == SweepMode.CONTINUOUS) radio_button.clicked.connect( - lambda: self.update_mode(SweepMode.CONTINOUS)) + lambda: self.update_mode(SweepMode.CONTINUOUS)) sweep_btn_layout.addWidget(radio_button) radio_button = QtWidgets.QRadioButton("Averaged sweep") @@ -93,6 +93,15 @@ class SweepSettingsWindow(QtWidgets.QWidget): lambda: self.update_mode(SweepMode.AVERAGE)) 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) # Log sweep