Implemented broadband scans.

This commit is contained in:
jupfi 2023-07-20 07:30:49 +02:00
parent e8e55682c9
commit 1dce515259
3 changed files with 141 additions and 19 deletions

View file

@ -81,14 +81,17 @@ class BroadbandController(ModuleController):
logger.debug("Frequency list: " + str(frequency_list)) logger.debug("Frequency list: " + str(frequency_list))
# Create a new broadband measurement object # Create a new broadband measurement object
self.module.model.current_broadcast_measurement = self.module.model.BroadbandMeasurement(frequency_list) self.module.model.current_broadcast_measurement = self.module.model.BroadbandMeasurement(frequency_list, self.module.model.frequency_step)
self.module.model.current_broadcast_measurement.received_measurement.connect(self.module.view.on_broadband_measurement_added) self.module.model.current_broadcast_measurement.received_measurement.connect(self.module.view.on_broadband_measurement_added)
self.module.model.current_broadcast_measurement.received_measurement.connect(self.on_broadband_measurement_added) self.module.model.current_broadcast_measurement.received_measurement.connect(self.on_broadband_measurement_added)
self.module.view.add_info_text("Starting broadband measurement.")
# Start the first measurement # Start the first measurement
self.module.view.add_info_text("Starting measurement at frequency: " + str(start_frequency))
self.module.nqrduck_signal.emit("set_frequency", str(start_frequency)) self.module.nqrduck_signal.emit("set_frequency", str(start_frequency))
self.module.nqrduck_signal.emit("start_measurement", None) self.module.nqrduck_signal.emit("start_measurement", None)
@pyqtSlot() @pyqtSlot()
def on_broadband_measurement_added(self): def on_broadband_measurement_added(self):
"""This slot is called when a single measurement is added to the broadband measurement. """This slot is called when a single measurement is added to the broadband measurement.
@ -102,5 +105,8 @@ class BroadbandController(ModuleController):
next_frequency = self.module.model.current_broadcast_measurement.get_next_measurement_frequency() next_frequency = self.module.model.current_broadcast_measurement.get_next_measurement_frequency()
logger.debug("Next frequency: " + str(next_frequency)) logger.debug("Next frequency: " + str(next_frequency))
# Start the next measurement # Start the next measurement
self.module.view.add_info_text("Starting measurement at frequency: " + str(next_frequency))
self.module.nqrduck_signal.emit("set_frequency", str(next_frequency)) self.module.nqrduck_signal.emit("set_frequency", str(next_frequency))
self.module.nqrduck_signal.emit("start_measurement", None) self.module.nqrduck_signal.emit("start_measurement", None)
else:
self.module.view.add_info_text("Broadband measurement finished.")

View file

@ -1,4 +1,5 @@
import logging import logging
import numpy as np
from collections import OrderedDict from collections import OrderedDict
from PyQt6.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication
from PyQt6.QtCore import pyqtSignal, QObject from PyQt6.QtCore import pyqtSignal, QObject
@ -60,12 +61,14 @@ class BroadbandModel(ModuleModel):
received_measurement = pyqtSignal() received_measurement = pyqtSignal()
def __init__(self, frequencies) -> None: def __init__(self, frequencies, frequency_step) -> None:
super().__init__() super().__init__()
self._single_frequency_measurements = OrderedDict() self._single_frequency_measurements = OrderedDict()
for frequency in frequencies: for frequency in frequencies:
self._single_frequency_measurements[frequency] = None self._single_frequency_measurements[frequency] = None
self.frequency_step = frequency_step
def add_measurement(self, measurement): def add_measurement(self, measurement):
"""This method adds a single measurement to the broadband measurement. """This method adds a single measurement to the broadband measurement.
@ -73,6 +76,7 @@ class BroadbandModel(ModuleModel):
measurement (Measurement): The measurement object.""" measurement (Measurement): The measurement object."""
logger.debug("Adding measurement to broadband measurement at frequency: %s" % str(measurement.target_frequency)) logger.debug("Adding measurement to broadband measurement at frequency: %s" % str(measurement.target_frequency))
self._single_frequency_measurements[measurement.target_frequency] = measurement self._single_frequency_measurements[measurement.target_frequency] = measurement
self.assemble_broadband_spectrum()
self.received_measurement.emit() self.received_measurement.emit()
QApplication.processEvents() QApplication.processEvents()
@ -104,6 +108,70 @@ class BroadbandModel(ModuleModel):
for frequency, measurement in self._single_frequency_measurements.items(): for frequency, measurement in self._single_frequency_measurements.items():
if measurement is not None: if measurement is not None:
return measurement return measurement
def get_finished_percentage(self):
"""Get the percentage of measurements that have been finished.
Returns:
float: The percentage of measurements that have been finished."""
finished_measurements = 0
for measurement in self._single_frequency_measurements.values():
if measurement is not None:
finished_measurements += 1
return finished_measurements / len(self._single_frequency_measurements) * 100
def assemble_broadband_spectrum(self):
"""This method assembles the broadband spectrum from the single frequency measurement data in frequency domain."""
# First we get all of the single frequency measurements that have already been measured
single_frequency_measurements = []
for measurement in self._single_frequency_measurements.values():
if measurement is not None:
single_frequency_measurements.append(measurement)
logger.debug("Assembling broadband spectrum from %d single frequency measurements." % len(single_frequency_measurements))
fdy_assembled = np.array([])
fdx_assembled = np.array([])
# We cut out step_size / 2 around 0 Hz of the spectrum and assemble the broadband spectrum
for measurement in single_frequency_measurements:
# This finds the center of the spectrum
center = np.where(measurement.fdx == 0)[0][0]
logger.debug("Center: %d" % center)
# This finds the nearest index of the lower and upper frequency step
logger.debug("Frequency step: %f" % self.frequency_step)
logger.debug(measurement.fdx)
idx_xf_lower = self.find_nearest(measurement.fdx, -self.frequency_step/2 * 1e-6)
idx_xf_upper = self.find_nearest(measurement.fdx, +self.frequency_step/2 * 1e-6)
# This interpolates the y values of the lower and upper frequency step
yf_interp_lower = np.interp(-self.frequency_step/2 * 1e-6, [measurement.fdx[idx_xf_lower], measurement.fdx[center]],
[measurement.fdy[idx_xf_lower][0], measurement.fdy[center][0]])
yf_interp_upper = np.interp(+self.frequency_step/2 * 1e-6, [measurement.fdx[center], measurement.fdx[idx_xf_upper]],
[measurement.fdy[center][0], measurement.fdy[idx_xf_lower][0]])
try:
fdy_assembled[-1] = (fdy_assembled[-1] + yf_interp_lower) / 2
fdy_assembled = np.append(fdy_assembled, measurement.fdy[center])
fdy_assembled = np.append(fdy_assembled, yf_interp_upper)
fdx_assembled[-1] = -self.frequency_step/2 * 1e-6 + measurement.target_frequency * 1e-6
fdx_assembled = np.append(fdx_assembled, measurement.target_frequency * 1e-6)
fdx_assembled = np.append(fdx_assembled, +self.frequency_step/2 * 1e-6 + measurement.target_frequency * 1e-6)
# On the first run we will get an Index Error
except IndexError:
fdy_assembled = np.array([yf_interp_lower, measurement.fdy[center][0], yf_interp_upper])
first_time_values = np.array([-self.frequency_step/2*1e-6, measurement.fdx[center] , +self.frequency_step/2*1e-6]) + measurement.target_frequency*1e-6
fdx_assembled = first_time_values
self.broadband_data_fdx = fdx_assembled.flatten()
self.broadband_data_fdy = fdy_assembled.flatten()
def find_nearest(self, array, value):
array = np.asarray(array)
idx = (np.abs(array - value)).argmin()
return idx
@property @property
def single_frequency_measurements(self): def single_frequency_measurements(self):
@ -113,3 +181,21 @@ class BroadbandModel(ModuleModel):
@single_frequency_measurements.setter @single_frequency_measurements.setter
def single_frequency_measurements(self, value): def single_frequency_measurements(self, value):
self._single_frequency_measurements = value self._single_frequency_measurements = value
@property
def broadband_data_fdx(self):
""" This property contains the broadband data and is assembled by the differen single_frequency measurements in frequency domain."""
return self._broadband_data_fdx
@broadband_data_fdx.setter
def broadband_data_fdx(self, value):
self._broadband_data_fdx = value
@property
def broadband_data_fdy(self):
""" This property contains the broadband data and is assembled by the differen single_frequency measurements in frequency domain."""
return self._broadband_data_fdy
@broadband_data_fdy.setter
def broadband_data_fdy(self, value):
self._broadband_data_fdy = value

View file

@ -1,6 +1,6 @@
import logging import logging
from PyQt6.QtCore import pyqtSlot, pyqtSignal from PyQt6.QtCore import pyqtSlot, pyqtSignal
from PyQt6.QtWidgets import QWidget, QMessageBox, QApplication from PyQt6.QtWidgets import QWidget, QMessageBox, QApplication, QLabel, QVBoxLayout
from nqrduck.module.module_view import ModuleView from nqrduck.module.module_view import ModuleView
from .widget import Ui_Form from .widget import Ui_Form
@ -26,6 +26,8 @@ class BroadbandView(ModuleView):
self.init_plots() self.init_plots()
self._ui_form.scrollAreaWidgetContents.setLayout(QVBoxLayout())
def _connect_signals(self) -> None: def _connect_signals(self) -> None:
self._ui_form.start_frequencyField.editingFinished.connect( self._ui_form.start_frequencyField.editingFinished.connect(
lambda: self.module.controller.change_start_frequency( lambda: self.module.controller.change_start_frequency(
@ -57,7 +59,7 @@ class BroadbandView(ModuleView):
def _start_measurement_clicked(self): def _start_measurement_clicked(self):
# Create a QMessageBox object # Create a QMessageBox object
msg_box = QMessageBox() msg_box = QMessageBox(parent=self)
msg_box.setText("Start the measurement?") msg_box.setText("Start the measurement?")
msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
@ -72,40 +74,50 @@ class BroadbandView(ModuleView):
self.start_broadband_measurement.emit() self.start_broadband_measurement.emit()
def init_plots(self): def init_plots(self):
# Initialization of broadband spectrum # Initialization of broadband spectrum
self._ui_form.broadbandPlot.canvas.ax.set_title("Broadband Spectrum")
self._ui_form.broadbandPlot.canvas.ax.set_xlim([0, 250]) self._ui_form.broadbandPlot.canvas.ax.set_xlim([0, 250])
self._ui_form.broadbandPlot.canvas.ax.set_xlabel("Frequency in MHz") self.set_broadband_labels()
self._ui_form.broadbandPlot.canvas.ax.set_ylabel("Amplitude a.u.")
self._ui_form.broadbandPlot.canvas.ax.grid()
# Initialization of last measurement time domain # Initialization of last measurement time domain
self._ui_form.time_domainPlot.canvas.ax.set_title("Last Time Domain")
self._ui_form.time_domainPlot.canvas.ax.set_xlim([0, 250]) self._ui_form.time_domainPlot.canvas.ax.set_xlim([0, 250])
self.set_timedomain_labels()
# Initialization of last measurement frequency domain
self._ui_form.frequency_domainPlot.canvas.ax.set_xlim([0, 250])
self.set_frequencydomain_labels()
def set_timedomain_labels(self):
self._ui_form.time_domainPlot.canvas.ax.set_title("Last Time Domain")
self._ui_form.time_domainPlot.canvas.ax.set_xlabel("time in us") self._ui_form.time_domainPlot.canvas.ax.set_xlabel("time in us")
self._ui_form.time_domainPlot.canvas.ax.set_ylabel("Amplitude a.u.") self._ui_form.time_domainPlot.canvas.ax.set_ylabel("Amplitude a.u.")
self._ui_form.time_domainPlot.canvas.ax.grid() self._ui_form.time_domainPlot.canvas.ax.grid()
# Initialization of last measurement frequency domain def set_frequencydomain_labels(self):
self._ui_form.frequency_domainPlot.canvas.ax.set_title("Last Frequency Domain") self._ui_form.frequency_domainPlot.canvas.ax.set_title("Last Frequency Domain")
self._ui_form.frequency_domainPlot.canvas.ax.set_xlim([0, 250]) self._ui_form.frequency_domainPlot.canvas.ax.set_xlabel("Frequency in MHz")
self._ui_form.frequency_domainPlot.canvas.ax.set_xlabel("time in us")
self._ui_form.frequency_domainPlot.canvas.ax.set_ylabel("Amplitude a.u.") self._ui_form.frequency_domainPlot.canvas.ax.set_ylabel("Amplitude a.u.")
self._ui_form.frequency_domainPlot.canvas.ax.grid() self._ui_form.frequency_domainPlot.canvas.ax.grid()
def set_broadband_labels(self):
self._ui_form.broadbandPlot.canvas.ax.set_title("Broadband Spectrum")
self._ui_form.broadbandPlot.canvas.ax.set_xlabel("Frequency in MHz")
self._ui_form.broadbandPlot.canvas.ax.set_ylabel("Amplitude a.u.")
self._ui_form.broadbandPlot.canvas.ax.grid()
@pyqtSlot(float) @pyqtSlot(float)
def on_start_frequency_change(self, start_frequency): def on_start_frequency_change(self, start_frequency):
logger.debug("Adjusting view to new start frequency: " + str(start_frequency)) logger.debug("Adjusting view to new start frequency: " + str(start_frequency * 1e-6))
self._ui_form.broadbandPlot.canvas.ax.set_xlim(left=start_frequency) self._ui_form.broadbandPlot.canvas.ax.set_xlim(left=start_frequency*1e-6)
self._ui_form.broadbandPlot.canvas.draw() self._ui_form.broadbandPlot.canvas.draw()
self._ui_form.broadbandPlot.canvas.flush_events() self._ui_form.broadbandPlot.canvas.flush_events()
self._ui_form.start_frequencyField.setText(str(start_frequency* 1e-6)) self._ui_form.start_frequencyField.setText(str(start_frequency* 1e-6))
@pyqtSlot(float) @pyqtSlot(float)
def on_stop_frequency_change(self, stop_frequency): def on_stop_frequency_change(self, stop_frequency):
logger.debug("Adjusting view to new stop frequency: " + str(stop_frequency)) logger.debug("Adjusting view to new stop frequency: " + str(stop_frequency * 1e-6))
self._ui_form.broadbandPlot.canvas.ax.set_xlim(right=stop_frequency) self._ui_form.broadbandPlot.canvas.ax.set_xlim(right=stop_frequency*1e-6)
self._ui_form.broadbandPlot.canvas.draw() self._ui_form.broadbandPlot.canvas.draw()
self._ui_form.broadbandPlot.canvas.flush_events() self._ui_form.broadbandPlot.canvas.flush_events()
self._ui_form.stop_frequencyField.setText(str(stop_frequency* 1e-6)) self._ui_form.stop_frequencyField.setText(str(stop_frequency* 1e-6))
@ -135,15 +147,33 @@ class BroadbandView(ModuleView):
td_plotter = self._ui_form.time_domainPlot.canvas.ax td_plotter = self._ui_form.time_domainPlot.canvas.ax
fd_plotter = self._ui_form.frequency_domainPlot.canvas.ax fd_plotter = self._ui_form.frequency_domainPlot.canvas.ax
broadband_plotter = self._ui_form.broadbandPlot.canvas.ax
td_plotter.clear() td_plotter.clear()
fd_plotter.clear() fd_plotter.clear()
broadband_plotter.clear()
td_plotter.plot(measurement.tdx, measurement.tdy) td_plotter.plot(measurement.tdx, measurement.tdy)
fd_plotter.plot(measurement.fdx, measurement.fdy) fd_plotter.plot(measurement.fdx * 1e-6, measurement.fdy * 1e-6)
broadband_plotter.plot(self.module.model.current_broadcast_measurement.broadband_data_fdx, self.module.model.current_broadcast_measurement.broadband_data_fdy)
self.set_timedomain_labels()
self.set_frequencydomain_labels()
self.set_broadband_labels()
self._ui_form.time_domainPlot.canvas.draw() self._ui_form.time_domainPlot.canvas.draw()
self._ui_form.frequency_domainPlot.canvas.draw() self._ui_form.frequency_domainPlot.canvas.draw()
self._ui_form.broadbandPlot.canvas.draw()
value = int(self.module.model.current_broadcast_measurement.get_finished_percentage())
logger.debug("Updating progress bar to: " + str(value))
self._ui_form.measurementProgress.setValue(value)
self._ui_form.measurementProgress.update()
QApplication.processEvents() QApplication.processEvents()
def add_info_text(self, text):
text_label = QLabel(text)
text_label.setStyleSheet("font-size: 14px;")
self._ui_form.scrollAreaWidgetContents.layout().addWidget(text_label)