mirror of
https://github.com/nqrduck/nqrduck-measurement.git
synced 2024-11-09 20:00:02 +00:00
Added fft view.
This commit is contained in:
parent
d094d7eae9
commit
ec9f40dad4
5 changed files with 154 additions and 26 deletions
|
@ -1,4 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
from PyQt6.QtCore import pyqtSlot
|
||||||
from nqrduck.module.module_controller import ModuleController
|
from nqrduck.module.module_controller import ModuleController
|
||||||
from nqrduck_spectrometer.measurement import Measurement
|
from nqrduck_spectrometer.measurement import Measurement
|
||||||
|
|
||||||
|
@ -8,6 +9,16 @@ class MeasurementController(ModuleController):
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def change_view_mode(self):
|
||||||
|
logger.debug("Changing view mode.")
|
||||||
|
if self.module.model.view_mode == self.module.model.FFT_VIEW:
|
||||||
|
self.module.model.view_mode = self.module.model.TIME_VIEW
|
||||||
|
else:
|
||||||
|
self.module.model.view_mode = self.module.model.FFT_VIEW
|
||||||
|
|
||||||
|
logger.debug("View mode changed to: " + self.module.model.view_mode)
|
||||||
|
|
||||||
def start_measurement(self):
|
def start_measurement(self):
|
||||||
logger.debug("Start measurement clicked")
|
logger.debug("Start measurement clicked")
|
||||||
self.module.view.measurement_dialog.show()
|
self.module.view.measurement_dialog.show()
|
||||||
|
@ -18,5 +29,6 @@ class MeasurementController(ModuleController):
|
||||||
|
|
||||||
if key == "measurement_data" and self.module.view.measurement_dialog.isVisible():
|
if key == "measurement_data" and self.module.view.measurement_dialog.isVisible():
|
||||||
logger.debug("Received single measurement.")
|
logger.debug("Received single measurement.")
|
||||||
self.module.model.single_measurement = value
|
self.module.model.displayed_measurement = value
|
||||||
|
self.module.model.add_measurement(value)
|
||||||
self.module.view.measurement_dialog.hide()
|
self.module.view.measurement_dialog.hide()
|
||||||
|
|
|
@ -7,17 +7,53 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class MeasurementModel(ModuleModel):
|
class MeasurementModel(ModuleModel):
|
||||||
|
|
||||||
single_measurement_changed = pyqtSignal(Measurement)
|
# This constants are used to determine which view is currently displayed.
|
||||||
|
FFT_VIEW = "fft"
|
||||||
|
TIME_VIEW = "time"
|
||||||
|
|
||||||
|
displayed_measurement_changed = pyqtSignal(Measurement)
|
||||||
|
measurements_changed = pyqtSignal(list)
|
||||||
|
view_mode_changed = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, module) -> None:
|
def __init__(self, module) -> None:
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
self.view_mode = self.TIME_VIEW
|
||||||
|
self.measurements = []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def single_measurement(self):
|
def view_mode(self):
|
||||||
"""Single measurement data."""
|
"""View mode of the measurement view.
|
||||||
return self._single_measurement
|
Can be either "time" or "fft"."""
|
||||||
|
return self._view_mode
|
||||||
|
|
||||||
@single_measurement.setter
|
@view_mode.setter
|
||||||
def single_measurement(self, value : Measurement):
|
def view_mode(self, value : str):
|
||||||
self._single_measurement = value
|
self._view_mode = value
|
||||||
self.single_measurement_changed.emit(value)
|
self.view_mode_changed.emit(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def measurements(self):
|
||||||
|
"""List of measurements."""
|
||||||
|
return self._measurements
|
||||||
|
|
||||||
|
@measurements.setter
|
||||||
|
def measurements(self, value : list[Measurement]):
|
||||||
|
self._measurements = value
|
||||||
|
self.measurements_changed.emit(value)
|
||||||
|
|
||||||
|
def add_measurement(self, measurement : Measurement):
|
||||||
|
"""Add a measurement to the list of measurements."""
|
||||||
|
self.measurements.append(measurement)
|
||||||
|
self.measurements_changed.emit(self.measurements)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def displayed_measurement(self):
|
||||||
|
"""Displayed measurement data.
|
||||||
|
This is the data that is displayed in the view.
|
||||||
|
It can be data in time domain or frequency domain."""
|
||||||
|
return self._displayed_measurement
|
||||||
|
|
||||||
|
@displayed_measurement.setter
|
||||||
|
def displayed_measurement(self, value : Measurement):
|
||||||
|
self._displayed_measurement = value
|
||||||
|
self.displayed_measurement_changed.emit(value)
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="plotterLayout" stretch="0">
|
<layout class="QVBoxLayout" name="plotterLayout" stretch="0,1">
|
||||||
<item>
|
<item>
|
||||||
<widget class="MplWidget" name="plotter" native="true">
|
<widget class="MplWidget" name="plotter" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -106,6 +106,46 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,1,0,0">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="fftButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>FFT</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="selectionBox"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -14,6 +14,7 @@ class MeasurementView(ModuleView):
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
|
||||||
|
# Set custom matplotlib parameters
|
||||||
mpl.rcParams.update({
|
mpl.rcParams.update({
|
||||||
"figure.facecolor": (0.0, 0.0, 0.0, 0.00), # transparent
|
"figure.facecolor": (0.0, 0.0, 0.0, 0.00), # transparent
|
||||||
"axes.facecolor": (0.0, 1.0, 0.0, 0.03), # green
|
"axes.facecolor": (0.0, 1.0, 0.0, 0.03), # green
|
||||||
|
@ -45,33 +46,56 @@ class MeasurementView(ModuleView):
|
||||||
self.measurement_dialog = self.MeasurementDialog()
|
self.measurement_dialog = self.MeasurementDialog()
|
||||||
|
|
||||||
# Connect signals
|
# Connect signals
|
||||||
self.module.model.single_measurement_changed.connect(self.update_single_measurement)
|
self.module.model.displayed_measurement_changed.connect(self.update_displayed_measurement)
|
||||||
|
self.module.model.view_mode_changed.connect(self.update_displayed_measurement)
|
||||||
|
|
||||||
self._ui_form.buttonStart.clicked.connect(self.on_measurement_start_button_clicked)
|
self._ui_form.buttonStart.clicked.connect(self.on_measurement_start_button_clicked)
|
||||||
|
self._ui_form.fftButton.clicked.connect(self.module.controller.change_view_mode)
|
||||||
|
|
||||||
def init_plotter(self):
|
def init_plotter(self):
|
||||||
plotter = self._ui_form.plotter
|
plotter = self._ui_form.plotter
|
||||||
|
plotter.canvas.ax.clear()
|
||||||
plotter.canvas.ax.set_xlim(0, 100)
|
plotter.canvas.ax.set_xlim(0, 100)
|
||||||
plotter.canvas.ax.set_ylim(0, 1)
|
plotter.canvas.ax.set_ylim(0, 1)
|
||||||
plotter.canvas.ax.set_xlabel("Time (µs)")
|
plotter.canvas.ax.set_xlabel("Time (µs)")
|
||||||
plotter.canvas.ax.set_ylabel("Amplitude (a.u.)")
|
plotter.canvas.ax.set_ylabel("Amplitude (a.u.)")
|
||||||
plotter.canvas.ax.set_title("Measurement data")
|
plotter.canvas.ax.set_title("Measurement data - Time domain")
|
||||||
|
plotter.canvas.ax.grid()
|
||||||
|
|
||||||
|
def change_to_time_view(self):
|
||||||
|
plotter = self._ui_form.plotter
|
||||||
|
plotter.canvas.ax.clear()
|
||||||
|
plotter.canvas.ax.set_xlabel("Time (µs)")
|
||||||
|
plotter.canvas.ax.set_ylabel("Amplitude (a.u.)")
|
||||||
|
plotter.canvas.ax.set_title("Measurement data - Time domain")
|
||||||
|
plotter.canvas.ax.grid()
|
||||||
|
|
||||||
|
def change_to_fft_view(self):
|
||||||
|
plotter = self._ui_form.plotter
|
||||||
|
plotter.canvas.ax.clear()
|
||||||
|
plotter.canvas.ax.set_xlabel("Frequency (MHz)")
|
||||||
|
plotter.canvas.ax.set_ylabel("Amplitude (a.u.)")
|
||||||
|
plotter.canvas.ax.set_title("Measurement data - Frequency domain")
|
||||||
plotter.canvas.ax.grid()
|
plotter.canvas.ax.grid()
|
||||||
plotter.canvas.draw()
|
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def update_single_measurement(self):
|
def update_displayed_measurement(self):
|
||||||
logger.debug("Updating single measurement view.")
|
logger.debug("Updating displayed measurement view.")
|
||||||
# Set the x data
|
plotter = self._ui_form.plotter
|
||||||
tdx = self.module.model.single_measurement.tdx
|
plotter.canvas.ax.clear()
|
||||||
tdy = self.module.model.single_measurement.tdy
|
try:
|
||||||
#correcting a offset in the time domain by subtracting the mean
|
if self.module.model.view_mode == self.module.model.FFT_VIEW:
|
||||||
tdy_mean = tdy[:,0]-np.mean(tdy)
|
self.change_to_fft_view()
|
||||||
self._ui_form.plotter.canvas.ax.set_xlabel("Time (µs)")
|
x = self.module.model.displayed_measurement.fdx
|
||||||
self._ui_form.plotter.canvas.ax.set_ylabel("Amplitude (a.u.)")
|
y = self.module.model.displayed_measurement.fdy
|
||||||
self._ui_form.plotter.canvas.ax.set_title("Measurement data")
|
else:
|
||||||
self._ui_form.plotter.canvas.ax.clear() # Clear the axes for the new plot
|
self.change_to_time_view()
|
||||||
self._ui_form.plotter.canvas.ax.plot(tdx, tdy_mean)
|
x = self.module.model.displayed_measurement.tdx
|
||||||
self._ui_form.plotter.canvas.ax.grid()
|
y = self.module.model.displayed_measurement.tdy
|
||||||
|
|
||||||
|
self._ui_form.plotter.canvas.ax.plot(x, y)
|
||||||
|
except AttributeError:
|
||||||
|
logger.debug("No measurement data to display.")
|
||||||
self._ui_form.plotter.canvas.draw()
|
self._ui_form.plotter.canvas.draw()
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
|
|
|
@ -68,6 +68,21 @@ class Ui_Form(object):
|
||||||
self.plotter.setSizePolicy(sizePolicy)
|
self.plotter.setSizePolicy(sizePolicy)
|
||||||
self.plotter.setObjectName("plotter")
|
self.plotter.setObjectName("plotter")
|
||||||
self.plotterLayout.addWidget(self.plotter)
|
self.plotterLayout.addWidget(self.plotter)
|
||||||
|
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
||||||
|
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||||
|
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
|
||||||
|
self.horizontalLayout_3.addItem(spacerItem1)
|
||||||
|
self.fftButton = QtWidgets.QToolButton(parent=Form)
|
||||||
|
self.fftButton.setObjectName("fftButton")
|
||||||
|
self.horizontalLayout_3.addWidget(self.fftButton)
|
||||||
|
self.selectionBox = QtWidgets.QSpinBox(parent=Form)
|
||||||
|
self.selectionBox.setObjectName("selectionBox")
|
||||||
|
self.horizontalLayout_3.addWidget(self.selectionBox)
|
||||||
|
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
|
||||||
|
self.horizontalLayout_3.addItem(spacerItem2)
|
||||||
|
self.horizontalLayout_3.setStretch(1, 1)
|
||||||
|
self.plotterLayout.addLayout(self.horizontalLayout_3)
|
||||||
|
self.plotterLayout.setStretch(1, 1)
|
||||||
self.horizontalLayout_2.addLayout(self.plotterLayout)
|
self.horizontalLayout_2.addLayout(self.plotterLayout)
|
||||||
self.horizontalLayout_2.setStretch(1, 1)
|
self.horizontalLayout_2.setStretch(1, 1)
|
||||||
self.horizontalLayout.addLayout(self.horizontalLayout_2)
|
self.horizontalLayout.addLayout(self.horizontalLayout_2)
|
||||||
|
@ -83,4 +98,5 @@ class Ui_Form(object):
|
||||||
self.label.setText(_translate("Form", "Target Frequency"))
|
self.label.setText(_translate("Form", "Target Frequency"))
|
||||||
self.label_2.setText(_translate("Form", "Averages"))
|
self.label_2.setText(_translate("Form", "Averages"))
|
||||||
self.buttonStart.setText(_translate("Form", "Start Measurement"))
|
self.buttonStart.setText(_translate("Form", "Start Measurement"))
|
||||||
|
self.fftButton.setText(_translate("Form", "FFT"))
|
||||||
from nqrduck.contrib.mplwidget import MplWidget
|
from nqrduck.contrib.mplwidget import MplWidget
|
||||||
|
|
Loading…
Reference in a new issue