From 4a2d9c5dc88c1ad3aaea3f874a8dd0b2da71cd76 Mon Sep 17 00:00:00 2001 From: "Rune B. Broberg" Date: Sat, 2 Nov 2019 22:40:54 +0100 Subject: [PATCH] Simple peak search --- NanoVNASaver/Analysis.py | 100 ++++++++++++++++++++++++++++++++++- NanoVNASaver/NanoVNASaver.py | 5 +- 2 files changed, 102 insertions(+), 3 deletions(-) diff --git a/NanoVNASaver/Analysis.py b/NanoVNASaver/Analysis.py index afd872d..895f312 100644 --- a/NanoVNASaver/Analysis.py +++ b/NanoVNASaver/Analysis.py @@ -975,6 +975,104 @@ class BandStopAnalysis(Analysis): self.result_label.setText("Analysis complete (" + str(len(self.app.data)) + " points)") +class SimplePeakSearchAnalysis(Analysis): + def __init__(self, app): + super().__init__(app) + self._widget = QtWidgets.QWidget() + outer_layout = QtWidgets.QFormLayout() + self._widget.setLayout(outer_layout) + + self.rbtn_data_group = QtWidgets.QButtonGroup() + self.rbtn_data_vswr = QtWidgets.QRadioButton("VSWR") + self.rbtn_data_resistance = QtWidgets.QRadioButton("Resistance") + self.rbtn_data_reactance = QtWidgets.QRadioButton("Reactance") + self.rbtn_data_s21_gain = QtWidgets.QRadioButton("S21 Gain") + self.rbtn_data_group.addButton(self.rbtn_data_vswr) + self.rbtn_data_group.addButton(self.rbtn_data_resistance) + self.rbtn_data_group.addButton(self.rbtn_data_reactance) + self.rbtn_data_group.addButton(self.rbtn_data_s21_gain) + + self.rbtn_data_s21_gain.setChecked(True) + + self.rbtn_peak_group = QtWidgets.QButtonGroup() + self.rbtn_peak_positive = QtWidgets.QRadioButton("Highest value") + self.rbtn_peak_negative = QtWidgets.QRadioButton("Lowest value") + self.rbtn_peak_group.addButton(self.rbtn_peak_positive) + self.rbtn_peak_group.addButton(self.rbtn_peak_negative) + + self.rbtn_peak_positive.setChecked(True) + + self.checkbox_move_marker = QtWidgets.QCheckBox() + + outer_layout.addRow(QtWidgets.QLabel("Settings")) + outer_layout.addRow("Data source", self.rbtn_data_vswr) + outer_layout.addRow("", self.rbtn_data_resistance) + outer_layout.addRow("", self.rbtn_data_reactance) + outer_layout.addRow("", self.rbtn_data_s21_gain) + outer_layout.addRow(PeakSearchAnalysis.QHLine()) + outer_layout.addRow("Peak type", self.rbtn_peak_positive) + outer_layout.addRow("", self.rbtn_peak_negative) + outer_layout.addRow(PeakSearchAnalysis.QHLine()) + outer_layout.addRow("Move marker to peak", self.checkbox_move_marker) + outer_layout.addRow(PeakSearchAnalysis.QHLine()) + + outer_layout.addRow(QtWidgets.QLabel("Results")) + + self.peak_frequency = QtWidgets.QLabel() + self.peak_value = QtWidgets.QLabel() + + outer_layout.addRow("Peak frequency:", self.peak_frequency) + outer_layout.addRow("Peak value:", self.peak_value) + + def runAnalysis(self): + if self.rbtn_data_vswr.isChecked(): + suffix = "" + data = [] + for d in self.app.data: + vswr = RFTools.calculateVSWR(d) + if vswr < 1: + vswr = float('inf') + data.append(vswr) + elif self.rbtn_data_resistance.isChecked(): + suffix = " \N{OHM SIGN}" + data = [] + for d in self.app.data: + re, im = RFTools.normalize50(d) + data.append(re) + elif self.rbtn_data_reactance.isChecked(): + suffix = " \N{OHM SIGN}" + data = [] + for d in self.app.data: + re, im = RFTools.normalize50(d) + data.append(im) + elif self.rbtn_data_s21_gain.isChecked(): + suffix = " dB" + data = [] + for d in self.app.data21: + data.append(RFTools.gain(d)) + else: + logger.warning("Searching for peaks on unknown data") + return + + if len(data) == 0: + return + + if self.rbtn_peak_positive.isChecked(): + idx_peak = np.argmax(data) + elif self.rbtn_peak_negative.isChecked(): + idx_peak = np.argmin(data) + else: + logger.warning("Searching for peaks, but neither looking at positive nor negative?") # Both is not yet in + return + + self.peak_frequency.setText(RFTools.formatFrequency(self.app.data[idx_peak].freq)) + self.peak_value.setText(str(round(data[idx_peak], 3)) + suffix) + + if self.checkbox_move_marker.isChecked() and len(self.app.markers) >= 1: + self.app.markers[0].setFrequency(str(self.app.data[idx_peak].freq)) + self.app.markers[0].frequencyInput.setText(RFTools.formatFrequency(self.app.data[idx_peak].freq)) + + class PeakSearchAnalysis(Analysis): class QHLine(QtWidgets.QFrame): def __init__(self): @@ -1025,7 +1123,7 @@ class PeakSearchAnalysis(Analysis): outer_layout.addRow(PeakSearchAnalysis.QHLine()) outer_layout.addRow("Peak type", self.rbtn_peak_positive) outer_layout.addRow("", self.rbtn_peak_negative) - # outer_layout.addRow("", self.rbtn_peak_both) + # outer_layout.addRow("", self.rbtn_peak_both) outer_layout.addRow(PeakSearchAnalysis.QHLine()) outer_layout.addRow("Max number of peaks", self.input_number_of_peaks) outer_layout.addRow("Move markers", self.checkbox_move_markers) diff --git a/NanoVNASaver/NanoVNASaver.py b/NanoVNASaver/NanoVNASaver.py index 8b9460c..adfd0ad 100644 --- a/NanoVNASaver/NanoVNASaver.py +++ b/NanoVNASaver/NanoVNASaver.py @@ -37,7 +37,7 @@ from .Marker import Marker from .SweepWorker import SweepWorker from .Touchstone import Touchstone from .Analysis import Analysis, LowPassAnalysis, HighPassAnalysis, BandPassAnalysis, BandStopAnalysis, \ - PeakSearchAnalysis, VSWRAnalysis + PeakSearchAnalysis, VSWRAnalysis, SimplePeakSearchAnalysis from .about import version as ver VID = 1155 @@ -2220,7 +2220,8 @@ class AnalysisWindow(QtWidgets.QWidget): self.analysis_list.addItem("Band-pass filter", BandPassAnalysis(self.app)) self.analysis_list.addItem("High-pass filter", HighPassAnalysis(self.app)) self.analysis_list.addItem("Band-stop filter", BandStopAnalysis(self.app)) - self.analysis_list.addItem("Peak search", PeakSearchAnalysis(self.app)) + # self.analysis_list.addItem("Peak search", PeakSearchAnalysis(self.app)) + self.analysis_list.addItem("Peak search", SimplePeakSearchAnalysis(self.app)) self.analysis_list.addItem("VSWR analysis", VSWRAnalysis(self.app)) select_analysis_layout.addRow("Analysis type", self.analysis_list) self.analysis_list.currentIndexChanged.connect(self.updateSelection)