From ca74b16b5fcf840ae166d8f5e7c454ef5bbf1a71 Mon Sep 17 00:00:00 2001 From: jupfi Date: Thu, 25 Apr 2024 20:19:15 +0200 Subject: [PATCH 1/6] New branch with new formbuilder. --- src/nqrduck_measurement/signalprocessing_options.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/nqrduck_measurement/signalprocessing_options.py b/src/nqrduck_measurement/signalprocessing_options.py index e1c9b95..1f52db3 100644 --- a/src/nqrduck_measurement/signalprocessing_options.py +++ b/src/nqrduck_measurement/signalprocessing_options.py @@ -2,12 +2,7 @@ import sympy from nqrduck_spectrometer.base_spectrometer_model import BaseSpectrometerModel -from nqrduck_spectrometer.pulseparameters import ( - FunctionOption, - GaussianFunction, - CustomFunction, - Function, -) +from nqrduck.helpers.functions import Function, GaussianFunction, CustomFunctiony # We implement the signal processing options as PulseParamterOptions because we can then easily use the automatic UI generation From 0cd27cde86760fad5380681bbfb0633d3963e339 Mon Sep 17 00:00:00 2001 From: "Pfitzer, Julia" Date: Fri, 26 Apr 2024 09:22:31 +0200 Subject: [PATCH 2/6] Switched to new formbuilder for singal processing. --- src/nqrduck_measurement/controller.py | 43 ++-------- .../signalprocessing_options.py | 81 +++++++++++++++---- 2 files changed, 73 insertions(+), 51 deletions(-) diff --git a/src/nqrduck_measurement/controller.py b/src/nqrduck_measurement/controller.py index 9b5d850..b07a48c 100644 --- a/src/nqrduck_measurement/controller.py +++ b/src/nqrduck_measurement/controller.py @@ -211,48 +211,19 @@ class MeasurementController(ModuleController): ) return - # We need to create a event which corresponds to the measurement. - event_duration = self.module.model.displayed_measurement.tdx[-1] * 1e-6 + measurement = self.module.model.displayed_measurement - 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) + dialog = Apodization(measurement, parent=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()) + function = dialog.get_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]) + apodized_measurement = dialog.apodization(function) - tdy_measurement = self.module.model.displayed_measurement.tdy * y_weight + dialog = None - 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) + self.module.model.displayed_measurement = apodized_measurement + self.module.model.add_measurement(apodized_measurement) diff --git a/src/nqrduck_measurement/signalprocessing_options.py b/src/nqrduck_measurement/signalprocessing_options.py index 1f52db3..cb9e365 100644 --- a/src/nqrduck_measurement/signalprocessing_options.py +++ b/src/nqrduck_measurement/signalprocessing_options.py @@ -1,11 +1,13 @@ """Signal processing options.""" - +import logging +from decimal import Decimal +import numpy as np import sympy -from nqrduck_spectrometer.base_spectrometer_model import BaseSpectrometerModel -from nqrduck.helpers.functions import Function, GaussianFunction, CustomFunctiony - -# We implement the signal processing options as PulseParamterOptions because we can then easily use the automatic UI generation +from nqrduck_spectrometer.measurement import Measurement +from nqrduck.helpers.functions import Function, GaussianFunction, CustomFunction +from nqrduck.helpers.formbuilder import DuckFormBuilder, DuckFormFunctionSelectionField +logger = logging.getLogger(__name__) class FIDFunction(Function): """The exponetial FID function.""" @@ -22,7 +24,7 @@ class FIDFunction(Function): self.add_parameter(Function.Parameter("T2star (microseconds)", "T2star", 10)) -class Apodization(BaseSpectrometerModel.PulseParameter): +class Apodization(DuckFormBuilder): """Apodization parameter. This parameter is used to apply apodization functions to the signal. @@ -32,15 +34,64 @@ class Apodization(BaseSpectrometerModel.PulseParameter): APODIZATION_FUNCTIONS (str): The name of the apodization functions option. """ - APODIZATION_FUNCTIONS = "Apodization functions" - - def __init__(self): + def __init__(self, measurement: Measurement, parent=None) -> None: """Apodization parameter.""" - super().__init__("Apodization") + super().__init__("Apodization", parent=parent) - self.add_option( - FunctionOption( - self.APODIZATION_FUNCTIONS, - [FIDFunction(), GaussianFunction(), CustomFunction()], - ), + self.measurement = measurement + functions = [ + FIDFunction(), + GaussianFunction(), + CustomFunction(), + ] + + self.duration = Decimal((measurement.tdx[-1] - measurement.tdx[0]) * 1e-6) + + function_selection_field = DuckFormFunctionSelectionField( + False, False, functions, self.duration, parent=parent, default_function=0 ) + + self.add_field(function_selection_field) + + def get_function(self) -> Function: + """Get the selected function. + + Returns: + Function: The selected function. + """ + return self.get_values()[0] + + def apodization(self, function : Function) -> None: + """Apply the apodization function to the measurement the object has been created to. + + Args: + function (Function): The apodization function. + + Returns: + Measurement: The apodized measurement. + """ + + # Get the y data weights from the function + resolution = ( + self.measurement.tdx[1] + - self.measurement.tdx[0] + ) * 1e-6 + + logger.debug("Resolution: %s", resolution) + logger.debug("Resolution (Dec): %s", Decimal(resolution)) + + y_weight = function.get_pulse_amplitude(self.duration, Decimal(resolution)) + # Append the last value to the end of the array + y_weight = np.append(y_weight, y_weight[-1]) + + tdy_measurement = self.measurement.tdy * y_weight + + apodized_measurement = Measurement( + self.measurement.tdx, + tdy_measurement, + target_frequency=self.measurement.target_frequency, + IF_frequency=self.measurement.IF_frequency, + ) + + return apodized_measurement + From c9e3dd1f44c0dcff1c7b40f1ba0eb1d64ca84e10 Mon Sep 17 00:00:00 2001 From: jupfi Date: Fri, 26 Apr 2024 11:22:19 +0200 Subject: [PATCH 3/6] Working apodization. --- src/nqrduck_measurement/controller.py | 3 +-- src/nqrduck_measurement/signalprocessing_options.py | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/nqrduck_measurement/controller.py b/src/nqrduck_measurement/controller.py index b07a48c..776cbbe 100644 --- a/src/nqrduck_measurement/controller.py +++ b/src/nqrduck_measurement/controller.py @@ -6,7 +6,6 @@ import numpy as np from decimal import Decimal from PyQt6.QtCore import pyqtSlot, pyqtSignal from PyQt6.QtWidgets import QApplication -from nqrduck_pulseprogrammer.view import OptionsDialog from nqrduck_spectrometer.pulsesequence import PulseSequence from .signalprocessing_options import Apodization from nqrduck.module.module_controller import ModuleController @@ -223,7 +222,7 @@ class MeasurementController(ModuleController): apodized_measurement = dialog.apodization(function) - dialog = None + dialog.deleteLater() self.module.model.displayed_measurement = apodized_measurement self.module.model.add_measurement(apodized_measurement) diff --git a/src/nqrduck_measurement/signalprocessing_options.py b/src/nqrduck_measurement/signalprocessing_options.py index cb9e365..5746fdb 100644 --- a/src/nqrduck_measurement/signalprocessing_options.py +++ b/src/nqrduck_measurement/signalprocessing_options.py @@ -29,9 +29,6 @@ class Apodization(DuckFormBuilder): This parameter is used to apply apodization functions to the signal. The apodization functions are used to reduce the noise in the signal. - - Attributes: - APODIZATION_FUNCTIONS (str): The name of the apodization functions option. """ def __init__(self, measurement: Measurement, parent=None) -> None: @@ -94,4 +91,3 @@ class Apodization(DuckFormBuilder): ) return apodized_measurement - From 775d6011f12305ade82483c1ec759db80865000b Mon Sep 17 00:00:00 2001 From: jupfi Date: Fri, 26 Apr 2024 14:41:43 +0200 Subject: [PATCH 4/6] Moved apodization to measurement. --- src/nqrduck_measurement/controller.py | 2 +- .../signalprocessing_options.py | 37 +------------------ 2 files changed, 3 insertions(+), 36 deletions(-) diff --git a/src/nqrduck_measurement/controller.py b/src/nqrduck_measurement/controller.py index 776cbbe..1c61f93 100644 --- a/src/nqrduck_measurement/controller.py +++ b/src/nqrduck_measurement/controller.py @@ -220,7 +220,7 @@ class MeasurementController(ModuleController): logger.debug("Apodization function: %s", function) - apodized_measurement = dialog.apodization(function) + apodized_measurement = measurement.apodization(function) dialog.deleteLater() diff --git a/src/nqrduck_measurement/signalprocessing_options.py b/src/nqrduck_measurement/signalprocessing_options.py index 5746fdb..25efa2b 100644 --- a/src/nqrduck_measurement/signalprocessing_options.py +++ b/src/nqrduck_measurement/signalprocessing_options.py @@ -42,7 +42,7 @@ class Apodization(DuckFormBuilder): CustomFunction(), ] - self.duration = Decimal((measurement.tdx[-1] - measurement.tdx[0]) * 1e-6) + self.duration = (self.measurement.tdx[-1] - self.measurement.tdx[0]) * 1e-6 function_selection_field = DuckFormFunctionSelectionField( False, False, functions, self.duration, parent=parent, default_function=0 @@ -57,37 +57,4 @@ class Apodization(DuckFormBuilder): Function: The selected function. """ return self.get_values()[0] - - def apodization(self, function : Function) -> None: - """Apply the apodization function to the measurement the object has been created to. - - Args: - function (Function): The apodization function. - - Returns: - Measurement: The apodized measurement. - """ - - # Get the y data weights from the function - resolution = ( - self.measurement.tdx[1] - - self.measurement.tdx[0] - ) * 1e-6 - - logger.debug("Resolution: %s", resolution) - logger.debug("Resolution (Dec): %s", Decimal(resolution)) - - y_weight = function.get_pulse_amplitude(self.duration, Decimal(resolution)) - # Append the last value to the end of the array - y_weight = np.append(y_weight, y_weight[-1]) - - tdy_measurement = self.measurement.tdy * y_weight - - apodized_measurement = Measurement( - self.measurement.tdx, - tdy_measurement, - target_frequency=self.measurement.target_frequency, - IF_frequency=self.measurement.IF_frequency, - ) - - return apodized_measurement + \ No newline at end of file From f847bdabcbb04b9023bd90f43887c21dff615e73 Mon Sep 17 00:00:00 2001 From: jupfi Date: Fri, 26 Apr 2024 16:07:26 +0200 Subject: [PATCH 5/6] Fixed bug with rejected apodization crashing the program. --- src/nqrduck_measurement/controller.py | 7 +++++-- src/nqrduck_measurement/signalprocessing_options.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/nqrduck_measurement/controller.py b/src/nqrduck_measurement/controller.py index 1c61f93..16b2c3c 100644 --- a/src/nqrduck_measurement/controller.py +++ b/src/nqrduck_measurement/controller.py @@ -215,8 +215,11 @@ class MeasurementController(ModuleController): dialog = Apodization(measurement, parent=self.module.view) result = dialog.exec() - if result: - function = dialog.get_function() + logger.debug("Dialog result: %s", result) + if not result: + return + + function = dialog.get_function() logger.debug("Apodization function: %s", function) diff --git a/src/nqrduck_measurement/signalprocessing_options.py b/src/nqrduck_measurement/signalprocessing_options.py index 25efa2b..be25fc0 100644 --- a/src/nqrduck_measurement/signalprocessing_options.py +++ b/src/nqrduck_measurement/signalprocessing_options.py @@ -45,7 +45,7 @@ class Apodization(DuckFormBuilder): self.duration = (self.measurement.tdx[-1] - self.measurement.tdx[0]) * 1e-6 function_selection_field = DuckFormFunctionSelectionField( - False, False, functions, self.duration, parent=parent, default_function=0 + text=None, tooltip=None, functions=functions, duration=self.duration, parent=parent, default_function=0 ) self.add_field(function_selection_field) From b5efd320745c6ea0bd693b899fefc9925437c7f3 Mon Sep 17 00:00:00 2001 From: jupfi Date: Fri, 26 Apr 2024 17:53:25 +0200 Subject: [PATCH 6/6] Version bump. --- CHANGELOG.md | 3 +++ pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59dc380..cf13fa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +### Version 0.0.3 (26-04-2024) +- Switched to new formbuilder. This should make implementation of signal processing methods more robust and easier. + ### Version 0.0.2 (17-04-2024) - Deployment to PyPi via github actions diff --git a/pyproject.toml b/pyproject.toml index 967e862..1e965e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ allow-direct-references = true [project] name = "nqrduck-measurement" -version = "0.0.2" +version = "0.0.3" authors = [ { name="jupfi", email="support@nqrduck.cool" }, ]