mirror of
https://github.com/nqrduck/nqrduck-measurement.git
synced 2024-11-09 20:00:02 +00:00
Added basic apodization.
This commit is contained in:
parent
6fef0c2753
commit
2e8084aae2
7 changed files with 114 additions and 22 deletions
|
@ -26,7 +26,10 @@ classifiers = [
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"matplotlib",
|
"matplotlib",
|
||||||
"pyqt6",
|
"pyqt6",
|
||||||
|
"sympy",
|
||||||
"NQRduck",
|
"NQRduck",
|
||||||
|
"nqrduck-pulseprogrammer",
|
||||||
|
"nqrduck-spectrometer",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.entry-points."nqrduck"]
|
[project.entry-points."nqrduck"]
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
import numpy as np
|
||||||
|
from decimal import Decimal
|
||||||
from PyQt6.QtCore import pyqtSlot, pyqtSignal
|
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.module.module_controller import ModuleController
|
||||||
from nqrduck_spectrometer.measurement import Measurement
|
from nqrduck_spectrometer.measurement import Measurement
|
||||||
|
|
||||||
|
@ -144,3 +149,51 @@ class MeasurementController(ModuleController):
|
||||||
self.module.nqrduck_signal.emit(
|
self.module.nqrduck_signal.emit(
|
||||||
"notification", ["Error", "File is not a valid measurement file."]
|
"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)
|
|
@ -20,6 +20,7 @@ class MeasurementModel(ModuleModel):
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
self.view_mode = self.TIME_VIEW
|
self.view_mode = self.TIME_VIEW
|
||||||
self.measurements = []
|
self.measurements = []
|
||||||
|
self._displayed_measurement = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def view_mode(self):
|
def view_mode(self):
|
||||||
|
|
|
@ -116,28 +116,28 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton_2">
|
<widget class="QPushButton" name="apodizationButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Apodization</string>
|
<string>Apodization</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton">
|
<widget class="QPushButton" name="baselineButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Baseline Correction</string>
|
<string>Baseline Correction</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton_3">
|
<widget class="QPushButton" name="peakButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Peak-Picking</string>
|
<string>Peak-Picking</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton_4">
|
<widget class="QPushButton" name="fittingButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Fitting</string>
|
<string>Fitting</string>
|
||||||
</property>
|
</property>
|
||||||
|
|
34
src/nqrduck_measurement/signalprocessing_options.py
Normal file
34
src/nqrduck_measurement/signalprocessing_options.py
Normal 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()],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,8 @@ class MeasurementView(ModuleView):
|
||||||
self.module.controller.set_frequency_failure.connect(self.on_set_frequency_failure)
|
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.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
|
# Call validator for buttonStart
|
||||||
|
|
||||||
# Add logos
|
# Add logos
|
||||||
|
@ -226,4 +228,3 @@ class MeasurementView(ModuleView):
|
||||||
self.spinner_movie.stop()
|
self.spinner_movie.stop()
|
||||||
super().hide()
|
super().hide()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,18 +68,18 @@ class Ui_Form(object):
|
||||||
self.spLabel.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
|
self.spLabel.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
|
||||||
self.spLabel.setObjectName("spLabel")
|
self.spLabel.setObjectName("spLabel")
|
||||||
self.settingsLayout.addWidget(self.spLabel)
|
self.settingsLayout.addWidget(self.spLabel)
|
||||||
self.pushButton_2 = QtWidgets.QPushButton(parent=Form)
|
self.apodizationButton = QtWidgets.QPushButton(parent=Form)
|
||||||
self.pushButton_2.setObjectName("pushButton_2")
|
self.apodizationButton.setObjectName("apodizationButton")
|
||||||
self.settingsLayout.addWidget(self.pushButton_2)
|
self.settingsLayout.addWidget(self.apodizationButton)
|
||||||
self.pushButton = QtWidgets.QPushButton(parent=Form)
|
self.baselineButton = QtWidgets.QPushButton(parent=Form)
|
||||||
self.pushButton.setObjectName("pushButton")
|
self.baselineButton.setObjectName("baselineButton")
|
||||||
self.settingsLayout.addWidget(self.pushButton)
|
self.settingsLayout.addWidget(self.baselineButton)
|
||||||
self.pushButton_3 = QtWidgets.QPushButton(parent=Form)
|
self.peakButton = QtWidgets.QPushButton(parent=Form)
|
||||||
self.pushButton_3.setObjectName("pushButton_3")
|
self.peakButton.setObjectName("peakButton")
|
||||||
self.settingsLayout.addWidget(self.pushButton_3)
|
self.settingsLayout.addWidget(self.peakButton)
|
||||||
self.pushButton_4 = QtWidgets.QPushButton(parent=Form)
|
self.fittingButton = QtWidgets.QPushButton(parent=Form)
|
||||||
self.pushButton_4.setObjectName("pushButton_4")
|
self.fittingButton.setObjectName("fittingButton")
|
||||||
self.settingsLayout.addWidget(self.pushButton_4)
|
self.settingsLayout.addWidget(self.fittingButton)
|
||||||
self.spsettingsButton = QtWidgets.QPushButton(parent=Form)
|
self.spsettingsButton = QtWidgets.QPushButton(parent=Form)
|
||||||
self.spsettingsButton.setObjectName("spsettingsButton")
|
self.spsettingsButton.setObjectName("spsettingsButton")
|
||||||
self.settingsLayout.addWidget(self.spsettingsButton)
|
self.settingsLayout.addWidget(self.spsettingsButton)
|
||||||
|
@ -137,10 +137,10 @@ class Ui_Form(object):
|
||||||
self.frequencyunitLabel.setText(_translate("Form", "MHz"))
|
self.frequencyunitLabel.setText(_translate("Form", "MHz"))
|
||||||
self.buttonStart.setText(_translate("Form", "Start Measurement"))
|
self.buttonStart.setText(_translate("Form", "Start Measurement"))
|
||||||
self.spLabel.setText(_translate("Form", "Signal Processing"))
|
self.spLabel.setText(_translate("Form", "Signal Processing"))
|
||||||
self.pushButton_2.setText(_translate("Form", "Apodization"))
|
self.apodizationButton.setText(_translate("Form", "Apodization"))
|
||||||
self.pushButton.setText(_translate("Form", "Baseline Correction"))
|
self.baselineButton.setText(_translate("Form", "Baseline Correction"))
|
||||||
self.pushButton_3.setText(_translate("Form", "Peak-Picking"))
|
self.peakButton.setText(_translate("Form", "Peak-Picking"))
|
||||||
self.pushButton_4.setText(_translate("Form", "Fitting"))
|
self.fittingButton.setText(_translate("Form", "Fitting"))
|
||||||
self.spsettingsButton.setText(_translate("Form", "Settings"))
|
self.spsettingsButton.setText(_translate("Form", "Settings"))
|
||||||
self.exportButton.setText(_translate("Form", "Export Measurement"))
|
self.exportButton.setText(_translate("Form", "Export Measurement"))
|
||||||
self.importButton.setText(_translate("Form", "Import Measurement"))
|
self.importButton.setText(_translate("Form", "Import Measurement"))
|
||||||
|
|
Loading…
Reference in a new issue