Merge branch 'main' of github.com:nqrduck/nqrduck-measurement

This commit is contained in:
jupfi 2024-02-28 09:59:50 +01:00
commit 25dd54c023
7 changed files with 114 additions and 22 deletions

View file

@ -26,7 +26,10 @@ classifiers = [
dependencies = [
"matplotlib",
"pyqt6",
"sympy",
"NQRduck",
"nqrduck-pulseprogrammer",
"nqrduck-spectrometer",
]
[project.entry-points."nqrduck"]

View file

@ -1,7 +1,12 @@
import logging
import json
import numpy as np
from decimal import Decimal
from PyQt6.QtCore import pyqtSlot, pyqtSignal
from PyQt6.QtWidgets import QWidget
import nqrduck.helpers.signalprocessing as sp
from nqrduck_pulseprogrammer.view import OptionsDialog
from nqrduck_spectrometer.pulsesequence import PulseSequence
from .signalprocessing_options import Apodization
from nqrduck.module.module_controller import ModuleController
from nqrduck_spectrometer.measurement import Measurement
@ -144,3 +149,51 @@ class MeasurementController(ModuleController):
self.module.nqrduck_signal.emit(
"notification", ["Error", "File is not a valid measurement file."]
)
def show_apodization_dialog(self) -> None:
"""Show apodization dialog."""
logger.debug("Showing apodization dialog.")
# First we check if there is a measurement.
if not self.module.model.displayed_measurement:
logger.debug("No measurement to apodize.")
self.module.nqrduck_signal.emit(
"notification", ["Error", "No measurement to apodize."]
)
return
# We need to create a event which corresponds to the measurement.
event_duration = self.module.model.displayed_measurement.tdx[-1] * 1e-6
event = PulseSequence.Event(name="Apodization", duration=str(event_duration))
parameter = Apodization()
parameter.start_x = 0
parameter.end_x = event_duration
dialog = OptionsDialog(event, parameter, self.module.view)
result = dialog.exec()
if result:
for option, function in dialog.return_functions.items():
logger.debug("Setting option %s of parameter %s in event %s to %s", option, parameter, event, function())
option.set_value(function())
# Get the function from the Apodization function
function = parameter.get_option_by_name(Apodization.APODIZATION_FUNCTIONS).value
logger.debug("Apodization function: %s", function)
# Get the y data weights from the function
resolution = (self.module.model.displayed_measurement.tdx[1] - self.module.model.displayed_measurement.tdx[0]) * 1e-6
y_weight = function.get_pulse_amplitude(event.duration, Decimal(resolution))
#Append the last point to the end of the array
y_weight = np.append(y_weight, y_weight[-1])
tdy_measurement = self.module.model.displayed_measurement.tdy * y_weight
measurement = Measurement(
self.module.model.displayed_measurement.tdx,
tdy_measurement,
target_frequency=self.module.model.displayed_measurement.target_frequency,
IF_frequency=self.module.model.displayed_measurement.IF_frequency,
)
self.module.model.displayed_measurement = measurement
self.module.model.add_measurement(measurement)

View file

@ -20,6 +20,7 @@ class MeasurementModel(ModuleModel):
super().__init__(module)
self.view_mode = self.TIME_VIEW
self.measurements = []
self._displayed_measurement = None
@property
def view_mode(self):

View file

@ -116,28 +116,28 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<widget class="QPushButton" name="apodizationButton">
<property name="text">
<string>Apodization</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="baselineButton">
<property name="text">
<string>Baseline Correction</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<widget class="QPushButton" name="peakButton">
<property name="text">
<string>Peak-Picking</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_4">
<widget class="QPushButton" name="fittingButton">
<property name="text">
<string>Fitting</string>
</property>

View file

@ -0,0 +1,34 @@
import sympy
from nqrduck_spectrometer.base_spectrometer_model import BaseSpectrometerModel
from nqrduck_spectrometer.pulseparameters import FunctionOption, NumericOption, GaussianFunction, CustomFunction, Function
# We implement the signal processing options as PulseParamterOptions because we can then easily use the automatic UI generation
class FIDFunction(Function):
"""The exponetial FID function."""
name = "FID"
def __init__(self) -> None:
expr = sympy.sympify("exp( -x / T2star )")
super().__init__(expr)
self.start_x = 0
self.end_x = 30
self.add_parameter(Function.Parameter("T2star (microseconds)", "T2star", 10))
class Apodization(BaseSpectrometerModel.PulseParameter):
APODIZATION_FUNCTIONS = "Apodization functions"
def __init__(self):
super().__init__("Apodization")
self.add_option(
FunctionOption(
self.APODIZATION_FUNCTIONS,
[FIDFunction(), GaussianFunction(), CustomFunction()],
),
)

View file

@ -60,6 +60,8 @@ class MeasurementView(ModuleView):
self.module.controller.set_frequency_failure.connect(self.on_set_frequency_failure)
self.module.controller.set_averages_failure.connect(self.on_set_averages_failure)
self._ui_form.apodizationButton.clicked.connect(self.module.controller.show_apodization_dialog)
# Call validator for buttonStart
# Add logos
@ -226,4 +228,3 @@ class MeasurementView(ModuleView):
self.spinner_movie.stop()
super().hide()

View file

@ -68,18 +68,18 @@ class Ui_Form(object):
self.spLabel.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.spLabel.setObjectName("spLabel")
self.settingsLayout.addWidget(self.spLabel)
self.pushButton_2 = QtWidgets.QPushButton(parent=Form)
self.pushButton_2.setObjectName("pushButton_2")
self.settingsLayout.addWidget(self.pushButton_2)
self.pushButton = QtWidgets.QPushButton(parent=Form)
self.pushButton.setObjectName("pushButton")
self.settingsLayout.addWidget(self.pushButton)
self.pushButton_3 = QtWidgets.QPushButton(parent=Form)
self.pushButton_3.setObjectName("pushButton_3")
self.settingsLayout.addWidget(self.pushButton_3)
self.pushButton_4 = QtWidgets.QPushButton(parent=Form)
self.pushButton_4.setObjectName("pushButton_4")
self.settingsLayout.addWidget(self.pushButton_4)
self.apodizationButton = QtWidgets.QPushButton(parent=Form)
self.apodizationButton.setObjectName("apodizationButton")
self.settingsLayout.addWidget(self.apodizationButton)
self.baselineButton = QtWidgets.QPushButton(parent=Form)
self.baselineButton.setObjectName("baselineButton")
self.settingsLayout.addWidget(self.baselineButton)
self.peakButton = QtWidgets.QPushButton(parent=Form)
self.peakButton.setObjectName("peakButton")
self.settingsLayout.addWidget(self.peakButton)
self.fittingButton = QtWidgets.QPushButton(parent=Form)
self.fittingButton.setObjectName("fittingButton")
self.settingsLayout.addWidget(self.fittingButton)
self.spsettingsButton = QtWidgets.QPushButton(parent=Form)
self.spsettingsButton.setObjectName("spsettingsButton")
self.settingsLayout.addWidget(self.spsettingsButton)
@ -137,10 +137,10 @@ class Ui_Form(object):
self.frequencyunitLabel.setText(_translate("Form", "MHz"))
self.buttonStart.setText(_translate("Form", "Start Measurement"))
self.spLabel.setText(_translate("Form", "Signal Processing"))
self.pushButton_2.setText(_translate("Form", "Apodization"))
self.pushButton.setText(_translate("Form", "Baseline Correction"))
self.pushButton_3.setText(_translate("Form", "Peak-Picking"))
self.pushButton_4.setText(_translate("Form", "Fitting"))
self.apodizationButton.setText(_translate("Form", "Apodization"))
self.baselineButton.setText(_translate("Form", "Baseline Correction"))
self.peakButton.setText(_translate("Form", "Peak-Picking"))
self.fittingButton.setText(_translate("Form", "Fitting"))
self.spsettingsButton.setText(_translate("Form", "Settings"))
self.exportButton.setText(_translate("Form", "Export Measurement"))
self.importButton.setText(_translate("Form", "Import Measurement"))