mirror of
https://github.com/nqrduck/nqrduck-broadband.git
synced 2025-01-03 13:18:10 +00:00
Implemented broadband scans.
This commit is contained in:
parent
e8e55682c9
commit
1dce515259
3 changed files with 141 additions and 19 deletions
|
@ -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.")
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue