Added ruff linter rules in .toml file and adjusted the different files accordingly.

This commit is contained in:
jupfi 2024-03-30 16:24:40 +01:00
parent b8a26e1eb1
commit 1e6c4d3083
8 changed files with 128 additions and 23 deletions

View file

@ -32,5 +32,31 @@ dependencies = [
"nqrduck-spectrometer", "nqrduck-spectrometer",
] ]
[project.optional-dependencies]
dev = [
"black",
"pydocstyle",
"pyupgrade",
"ruff",
]
[project.entry-points."nqrduck"] [project.entry-points."nqrduck"]
"nqrduck-measurement" = "nqrduck_measurement.measurement:Measurement" "nqrduck-measurement" = "nqrduck_measurement.measurement:Measurement"
[tool.ruff]
exclude = [
"widget.py",
]
[tool.ruff.lint]
extend-select = [
"UP", # pyupgrade
"D", # pydocstyle
]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
[tool.ruff.lint.pydocstyle]
convention = "google"

View file

@ -1 +1,5 @@
"""Init file for the nqrduck-measurement module.
Used to import the Measurement module.
"""
from .measurement import Measurement as Module from .measurement import Measurement as Module

View file

@ -1,3 +1,4 @@
"""Controller for the measurement module."""
import logging import logging
import json import json
import numpy as np import numpy as np
@ -5,7 +6,6 @@ from decimal import Decimal
from PyQt6.QtCore import pyqtSlot, pyqtSignal from PyQt6.QtCore import pyqtSlot, pyqtSignal
from PyQt6.QtGui import QValidator from PyQt6.QtGui import QValidator
from PyQt6.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication
import nqrduck.helpers.signalprocessing as sp
from nqrduck_pulseprogrammer.view import OptionsDialog from nqrduck_pulseprogrammer.view import OptionsDialog
from nqrduck_spectrometer.pulsesequence import PulseSequence from nqrduck_spectrometer.pulsesequence import PulseSequence
from .signalprocessing_options import Apodization from .signalprocessing_options import Apodization
@ -16,10 +16,22 @@ logger = logging.getLogger(__name__)
class MeasurementController(ModuleController): class MeasurementController(ModuleController):
"""Controller for the measurement module.
This class is responsible for handling the signals from the view and the module and updating the model.
Args:
module (Module): The module instance.
Attributes:
set_frequency_failure (pyqtSignal): Signal emitted when setting the frequency fails.
set_averages_failure (pyqtSignal): Signal emitted when setting the averages fails.
"""
set_frequency_failure = pyqtSignal() set_frequency_failure = pyqtSignal()
set_averages_failure = pyqtSignal() set_averages_failure = pyqtSignal()
def __init__(self, module): def __init__(self, module):
"""Initialize the controller."""
super().__init__(module) super().__init__(module)
@pyqtSlot(str) @pyqtSlot(str)
@ -30,8 +42,8 @@ class MeasurementController(ModuleController):
value (str): Frequency in MHz. value (str): Frequency in MHz.
Raises: Raises:
ValueError: If value cannot be converted to float.""" ValueError: If value cannot be converted to float.
"""
# Use validator # Use validator
if self.module.model.validator_measurement_frequency.validate(value, 0) == QValidator.State.Acceptable: if self.module.model.validator_measurement_frequency.validate(value, 0) == QValidator.State.Acceptable:
self.module.model.measurement_frequency = float(value) * 1e6 self.module.model.measurement_frequency = float(value) * 1e6
@ -93,12 +105,12 @@ class MeasurementController(ModuleController):
else: else:
self.module.view._ui_form.buttonStart.setEnabled(False) self.module.view._ui_form.buttonStart.setEnabled(False)
def process_signals(self, key: str, value: object): def process_signals(self, key: str, value: object) -> None:
"""Process incoming signal from the nqrduck module. """Process incoming signal from the nqrduck module.
Arguments: Args:
key (str) -- The key of the signal. key (str): The key of the signal.
value (object) -- The value of the signal. value (object): The value of the signal.
""" """
logger.debug( logger.debug(
"Measurement Dialog is visible: " "Measurement Dialog is visible: "
@ -166,7 +178,7 @@ class MeasurementController(ModuleController):
logger.debug("Loading measurement.") logger.debug("Loading measurement.")
try: try:
with open(file_name, "r") as f: with open(file_name) as f:
measurement = Measurement.from_json(json.load(f)) measurement = Measurement.from_json(json.load(f))
self.module.model.add_measurement(measurement) self.module.model.add_measurement(measurement)
self.module.model.displayed_measurement = measurement self.module.model.displayed_measurement = measurement

View file

@ -1,3 +1,4 @@
"""Module initialization file for the nqrduck-measurement module."""
from nqrduck.module.module import Module from nqrduck.module.module import Module
from .model import MeasurementModel from .model import MeasurementModel
from .view import MeasurementView from .view import MeasurementView

View file

@ -1,3 +1,4 @@
"""Model for the measurement module."""
import logging import logging
from PyQt6.QtCore import pyqtSignal from PyQt6.QtCore import pyqtSignal
from nqrduck_spectrometer.measurement import Measurement from nqrduck_spectrometer.measurement import Measurement
@ -7,6 +8,31 @@ from nqrduck.helpers.validators import DuckFloatValidator, DuckIntValidator
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class MeasurementModel(ModuleModel): class MeasurementModel(ModuleModel):
"""Model for the measurement module.
This class is responsible for storing the data of the measurement module.
Attributes:
FILE_EXTENSION (str): The file extension of the measurement files.
FFT_VIEW (str): The view mode for the FFT view.
TIME_VIEW (str): The view mode for the time view.
displayed_measurement_changed (pyqtSignal): Signal emitted when the displayed measurement changes.
measurements_changed (pyqtSignal): Signal emitted when the list of measurements changes.
view_mode_changed (pyqtSignal): Signal emitted when the view mode changes.
measurement_frequency_changed (pyqtSignal): Signal emitted when the measurement frequency changes.
averages_changed (pyqtSignal): Signal emitted when the number of averages changes.
view_mode (str): The view mode of the measurement view.
measurements (list): List of measurements.
displayed_measurement (Measurement): The displayed measurement data.
measurement_frequency (float): The measurement frequency.
averages (int): The number of averages.
validator_measurement_frequency (DuckFloatValidator): Validator for the measurement frequency.
validator_averages (DuckIntValidator): Validator for the number of averages.
"""
FILE_EXTENSION = "meas" FILE_EXTENSION = "meas"
# This constants are used to determine which view is currently displayed. # This constants are used to determine which view is currently displayed.
@ -21,6 +47,7 @@ class MeasurementModel(ModuleModel):
averages_changed = pyqtSignal(int) averages_changed = pyqtSignal(int)
def __init__(self, module) -> None: def __init__(self, module) -> None:
"""Initialize the model."""
super().__init__(module) super().__init__(module)
self.view_mode = self.TIME_VIEW self.view_mode = self.TIME_VIEW
self.measurements = [] self.measurements = []
@ -33,9 +60,11 @@ class MeasurementModel(ModuleModel):
self.averages = 1 self.averages = 1
@property @property
def view_mode(self): def view_mode(self) -> str:
"""View mode of the measurement view. """View mode of the measurement view.
Can be either "time" or "fft"."""
Can be either "time" or "fft".
"""
return self._view_mode return self._view_mode
@view_mode.setter @view_mode.setter
@ -61,8 +90,10 @@ class MeasurementModel(ModuleModel):
@property @property
def displayed_measurement(self): def displayed_measurement(self):
"""Displayed measurement data. """Displayed measurement data.
This is the data that is displayed in the view. This is the data that is displayed in the view.
It can be data in time domain or frequency domain.""" It can be data in time domain or frequency domain.
"""
return self._displayed_measurement return self._displayed_measurement
@displayed_measurement.setter @displayed_measurement.setter

View file

@ -1,6 +1,7 @@
"""Signal processing options."""
import sympy import sympy
from nqrduck_spectrometer.base_spectrometer_model import BaseSpectrometerModel from nqrduck_spectrometer.base_spectrometer_model import BaseSpectrometerModel
from nqrduck_spectrometer.pulseparameters import FunctionOption, NumericOption, GaussianFunction, CustomFunction, Function from nqrduck_spectrometer.pulseparameters import FunctionOption, GaussianFunction, CustomFunction, Function
# We implement the signal processing options as PulseParamterOptions because we can then easily use the automatic UI generation # We implement the signal processing options as PulseParamterOptions because we can then easily use the automatic UI generation
@ -10,6 +11,7 @@ class FIDFunction(Function):
name = "FID" name = "FID"
def __init__(self) -> None: def __init__(self) -> None:
"""Exponential FID function."""
expr = sympy.sympify("exp( -x / T2star )") expr = sympy.sympify("exp( -x / T2star )")
super().__init__(expr) super().__init__(expr)
self.start_x = 0 self.start_x = 0
@ -19,9 +21,18 @@ class FIDFunction(Function):
class Apodization(BaseSpectrometerModel.PulseParameter): class Apodization(BaseSpectrometerModel.PulseParameter):
"""Apodization parameter.
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.
"""
APODIZATION_FUNCTIONS = "Apodization functions" APODIZATION_FUNCTIONS = "Apodization functions"
def __init__(self): def __init__(self):
"""Apodization parameter."""
super().__init__("Apodization") super().__init__("Apodization")
self.add_option( self.add_option(

View file

@ -1,7 +1,6 @@
"""View for the measurement module."""
import logging import logging
import numpy as np import numpy as np
from pathlib import Path
import matplotlib as mpl
from PyQt6.QtWidgets import QWidget, QDialog, QLabel, QVBoxLayout from PyQt6.QtWidgets import QWidget, QDialog, QLabel, QVBoxLayout
from PyQt6.QtGui import QValidator from PyQt6.QtGui import QValidator
from PyQt6.QtCore import pyqtSlot, Qt from PyQt6.QtCore import pyqtSlot, Qt
@ -13,7 +12,20 @@ from .widget import Ui_Form
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class MeasurementView(ModuleView): class MeasurementView(ModuleView):
"""View for the measurement module.
This class is responsible for displaying the measurement data and handling the user input.
Args:
module (Module): The module instance.
Attributes:
widget (QWidget): The widget of the view.
_ui_form (Ui_Form): The form of the widget.
measurement_dialog (MeasurementDialog): The dialog shown when the measurement is started.
"""
def __init__(self, module): def __init__(self, module):
"""Initialize the measurement view."""
super().__init__(module) super().__init__(module)
widget = QWidget() widget = QWidget()
@ -101,8 +113,7 @@ class MeasurementView(ModuleView):
@pyqtSlot() @pyqtSlot()
def update_displayed_measurement(self) -> None: def update_displayed_measurement(self) -> None:
"""Update displayed measurement data. """Update displayed measurement data."""
"""
logger.debug("Updating displayed measurement view.") logger.debug("Updating displayed measurement view.")
plotter = self._ui_form.plotter plotter = self._ui_form.plotter
plotter.canvas.ax.clear() plotter.canvas.ax.clear()
@ -173,7 +184,8 @@ class MeasurementView(ModuleView):
Args: Args:
widget (QLineEdit): The widget to update. widget (QLineEdit): The widget to update.
validator (QValidator): The validator to use for the widget.""" validator (QValidator): The validator to use for the widget.
"""
if ( if (
validator.validate(widget.text(), 0) validator.validate(widget.text(), 0)
== QValidator.State.Acceptable == QValidator.State.Acceptable
@ -189,9 +201,15 @@ class MeasurementView(ModuleView):
class MeasurementDialog(QDialog): class MeasurementDialog(QDialog):
""" This Dialog is shown when the measurement is started and therefore blocks the main window. """This Dialog is shown when the measurement is started and therefore blocks the main window.
It shows the duck animation and a message."""
It shows the duck animation and a message.
Attributes:
finished (bool): True if the spinner movie is finished.
"""
def __init__(self): def __init__(self):
"""Initialize the dialog."""
super().__init__() super().__init__()
self.finished = True self.finished = True
self.setModal(True) self.setModal(True)
@ -211,10 +229,12 @@ class MeasurementView(ModuleView):
self.spinner_movie.start() self.spinner_movie.start()
def on_movie_finished(self): def on_movie_finished(self) -> None:
"""Called when the spinner movie is finished."""
self.finished = True self.finished = True
def hide(self): def hide(self) -> None:
"""Hide the dialog and stop the spinner movie."""
while not self.finished: while not self.finished:
continue continue
self.spinner_movie.stop() self.spinner_movie.stop()

View file

@ -9,7 +9,7 @@
from PyQt6 import QtCore, QtGui, QtWidgets from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_Form(object): class Ui_Form:
def setupUi(self, Form): def setupUi(self, Form):
Form.setObjectName("Form") Form.setObjectName("Form")
Form.resize(1920, 1080) Form.resize(1920, 1080)