mirror of
https://github.com/nqrduck/nqrduck-spectrometer.git
synced 2024-11-09 12:30:01 +00:00
Linting
This commit is contained in:
parent
3a455428e5
commit
a758d20c03
15 changed files with 661 additions and 195 deletions
|
@ -32,5 +32,31 @@ dependencies = [
|
||||||
"scipy",
|
"scipy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = [
|
||||||
|
"black",
|
||||||
|
"pydocstyle",
|
||||||
|
"pyupgrade",
|
||||||
|
"ruff",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
exclude = [
|
||||||
|
"widget.py",
|
||||||
|
"base_spectrometer_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"
|
||||||
|
|
||||||
[project.entry-points."nqrduck"]
|
[project.entry-points."nqrduck"]
|
||||||
"nqrduck-spectrometer" = "nqrduck_spectrometer.spectrometer:Spectrometer"
|
"nqrduck-spectrometer" = "nqrduck_spectrometer.spectrometer:Spectrometer"
|
|
@ -1 +1,2 @@
|
||||||
|
"""Init for importing the module."""
|
||||||
from .spectrometer import Spectrometer as Module
|
from .spectrometer import Spectrometer as Module
|
|
@ -1,25 +1,37 @@
|
||||||
|
"""Base Spectrometer Module."""
|
||||||
|
|
||||||
from PyQt6.QtCore import pyqtSignal
|
from PyQt6.QtCore import pyqtSignal
|
||||||
from nqrduck.module.module import Module
|
from nqrduck.module.module import Module
|
||||||
|
|
||||||
|
|
||||||
class BaseSpectrometer(Module):
|
class BaseSpectrometer(Module):
|
||||||
"""Base class for all spectrometers. All spectrometers should inherit from this class."""
|
"""Base class for all spectrometers. All spectrometers should inherit from this class.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
Model (SpectrometerModel) : The model of the spectrometer
|
||||||
|
View (SpectrometerView) : The view of the spectrometer
|
||||||
|
Controller (SpectrometerController) : The controller of the spectrometer
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
change_spectrometer (str) : Signal emitted when the spectrometer is changed
|
||||||
|
"""
|
||||||
|
|
||||||
change_spectrometer = pyqtSignal(str)
|
change_spectrometer = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, model, view, controller):
|
def __init__(self, model, view, controller):
|
||||||
|
"""Initializes the spectrometer."""
|
||||||
super().__init__(model, None, controller)
|
super().__init__(model, None, controller)
|
||||||
# This stops the view from being added to the main window.
|
# This stops the view from being added to the main window.
|
||||||
self.view = None
|
self.view = None
|
||||||
self.settings_view = view(self)
|
self.settings_view = view(self)
|
||||||
|
|
||||||
def set_active(self):
|
def set_active(self):
|
||||||
"""Sets the spectrometer as the active spectrometer.
|
"""Sets the spectrometer as the active spectrometer."""
|
||||||
"""
|
|
||||||
self.change_spectrometer.emit(self._model.name)
|
self.change_spectrometer.emit(self._model.name)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def settings_view(self):
|
def settings_view(self):
|
||||||
"""The settings view of the spectrometer.
|
"""The settings view of the spectrometer."""
|
||||||
"""
|
|
||||||
return self._settings_view
|
return self._settings_view
|
||||||
|
|
||||||
@settings_view.setter
|
@settings_view.setter
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
|
"""Base class for all spectrometer controllers."""
|
||||||
|
|
||||||
from nqrduck.module.module_controller import ModuleController
|
from nqrduck.module.module_controller import ModuleController
|
||||||
|
|
||||||
|
|
||||||
class BaseSpectrometerController(ModuleController):
|
class BaseSpectrometerController(ModuleController):
|
||||||
"""The base class for all spectrometer controllers."""
|
"""The base class for all spectrometer controllers."""
|
||||||
|
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
|
"""Initializes the spectrometer controller."""
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
|
||||||
def start_measurement(self):
|
def start_measurement(self):
|
||||||
"""Starts the measurement.
|
"""Starts the measurement.
|
||||||
|
|
||||||
This method should be called when the measurement is started.
|
This method should be called when the measurement is started.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -17,4 +22,5 @@ class BaseSpectrometerController(ModuleController):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def set_averages(self, value):
|
def set_averages(self, value):
|
||||||
|
"""Sets the number of averages."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
|
@ -1,53 +1,67 @@
|
||||||
|
"""The base class for all spectrometer models."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from PyQt6.QtCore import pyqtSlot, pyqtSignal, QObject
|
from PyQt6.QtGui import QPixmap
|
||||||
from nqrduck.module.module_model import ModuleModel
|
from nqrduck.module.module_model import ModuleModel
|
||||||
from .settings import Setting
|
from .settings import Setting
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class BaseSpectrometerModel(ModuleModel):
|
class BaseSpectrometerModel(ModuleModel):
|
||||||
"""The base class for all spectrometer models.
|
"""The base class for all spectrometer models.
|
||||||
|
|
||||||
It contains the settings and pulse parameters of the spectrometer.
|
It contains the settings and pulse parameters of the spectrometer.
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
module (Module) -- The module that the spectrometer is connected to
|
module (Module) : The module that the spectrometer is connected to
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
settings (OrderedDict) -- The settings of the spectrometer
|
settings (OrderedDict) : The settings of the spectrometer
|
||||||
pulse_parameter_options (OrderedDict) -- The pulse parameter options of the spectrometer
|
pulse_parameter_options (OrderedDict) : The pulse parameter options of the spectrometer
|
||||||
"""
|
"""
|
||||||
|
|
||||||
settings: OrderedDict
|
settings: OrderedDict
|
||||||
pulse_parameter_options: OrderedDict
|
pulse_parameter_options: OrderedDict
|
||||||
|
|
||||||
class PulseParameter:
|
class PulseParameter:
|
||||||
"""A pulse parameter is a value that can be different for each event in a pulse sequence.
|
"""A pulse parameter is a value that can be different for each event in a pulse sequence.
|
||||||
|
|
||||||
E.g. the transmit pulse power or the phase of the transmit pulse.
|
E.g. the transmit pulse power or the phase of the transmit pulse.
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
name (str) -- The name of the pulse parameter
|
name (str) : The name of the pulse parameter
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
name (str) -- The name of the pulse parameter
|
name (str) : The name of the pulse parameter
|
||||||
options (OrderedDict) -- The options of the pulse parameter
|
options (OrderedDict) : The options of the pulse parameter
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str):
|
def __init__(self, name: str):
|
||||||
"""Initializes the pulse parameter.
|
"""Initializes the pulse parameter.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
name (str) -- The name of the pulse parameter
|
name (str) : The name of the pulse parameter
|
||||||
"""
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
self.options = list()
|
self.options = list()
|
||||||
|
|
||||||
def get_pixmap(self):
|
def get_pixmap(self) -> QPixmap:
|
||||||
|
"""Gets the pixmap of the pulse parameter.
|
||||||
|
|
||||||
|
Implment this method in the derived class.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
QPixmap : The pixmap of the pulse parameter
|
||||||
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def add_option(self, option: "Option") -> None:
|
def add_option(self, option: "Option") -> None:
|
||||||
"""Adds an option to the pulse parameter.
|
"""Adds an option to the pulse parameter.
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
option (Option) -- The option to add
|
option (Option) : The option to add
|
||||||
"""
|
"""
|
||||||
self.options.append(option)
|
self.options.append(option)
|
||||||
|
|
||||||
|
@ -55,41 +69,44 @@ class BaseSpectrometerModel(ModuleModel):
|
||||||
"""Gets the options of the pulse parameter.
|
"""Gets the options of the pulse parameter.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list -- The options of the pulse parameter
|
list : The options of the pulse parameter
|
||||||
"""
|
"""
|
||||||
return self.options
|
return self.options
|
||||||
|
|
||||||
def get_option_by_name(self, name: str) -> "Option":
|
def get_option_by_name(self, name: str) -> "Option":
|
||||||
"""Gets an option by its name.
|
"""Gets an option by its name.
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
name (str) -- The name of the option
|
name (str) : The name of the option
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Option -- The option with the specified name
|
Option : The option with the specified name
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError -- If no option with the specified name is found
|
ValueError : If no option with the specified name is found
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for option in self.options:
|
for option in self.options:
|
||||||
if option.name == name:
|
if option.name == name:
|
||||||
return option
|
return option
|
||||||
raise ValueError("Option with name %s not found" % name)
|
raise ValueError("Option with name %s not found" % name)
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
"""Initializes the spectrometer model.
|
"""Initializes the spectrometer model.
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
module (Module) -- The module that the spectrometer is connected to
|
module (Module) : The module that the spectrometer is connected to
|
||||||
"""
|
"""
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
self.settings = OrderedDict()
|
self.settings = OrderedDict()
|
||||||
self.pulse_parameter_options = OrderedDict()
|
self.pulse_parameter_options = OrderedDict()
|
||||||
|
|
||||||
def add_setting(self, setting: Setting, category: str) -> None:
|
def add_setting(self, setting: Setting, category: str) -> None:
|
||||||
|
"""Adds a setting to the spectrometer.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
setting (Setting) : The setting to add
|
||||||
|
category (str) : The category of the setting
|
||||||
|
"""
|
||||||
if category not in self.settings.keys():
|
if category not in self.settings.keys():
|
||||||
self.settings[category] = []
|
self.settings[category] = []
|
||||||
self.settings[category].append(setting)
|
self.settings[category].append(setting)
|
||||||
|
@ -97,14 +114,14 @@ class BaseSpectrometerModel(ModuleModel):
|
||||||
def get_setting_by_name(self, name: str) -> Setting:
|
def get_setting_by_name(self, name: str) -> Setting:
|
||||||
"""Gets a setting by its name.
|
"""Gets a setting by its name.
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
name (str) -- The name of the setting
|
name (str) : The name of the setting
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Setting -- The setting with the specified name
|
Setting : The setting with the specified name
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError -- If no setting with the specified name is found
|
ValueError : If no setting with the specified name is found
|
||||||
"""
|
"""
|
||||||
for category in self.settings.keys():
|
for category in self.settings.keys():
|
||||||
for setting in self.settings[category]:
|
for setting in self.settings[category]:
|
||||||
|
@ -112,12 +129,15 @@ class BaseSpectrometerModel(ModuleModel):
|
||||||
return setting
|
return setting
|
||||||
raise ValueError("Setting with name %s not found" % name)
|
raise ValueError("Setting with name %s not found" % name)
|
||||||
|
|
||||||
def add_pulse_parameter_option(self, name : str, pulse_parameter_class : PulseParameter) -> None:
|
def add_pulse_parameter_option(
|
||||||
|
self, name: str, pulse_parameter_class: PulseParameter
|
||||||
|
) -> None:
|
||||||
"""Adds a pulse parameter option to the spectrometer.
|
"""Adds a pulse parameter option to the spectrometer.
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
name (str) -- The name of the pulse parameter
|
name (str) : The name of the pulse parameter
|
||||||
pulse_parameter_class (PulseParameter) -- The pulse parameter class"""
|
pulse_parameter_class (PulseParameter) : The pulse parameter class
|
||||||
|
"""
|
||||||
self.pulse_parameter_options[name] = pulse_parameter_class
|
self.pulse_parameter_options[name] = pulse_parameter_class
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
|
"""The Base Class for all Spectrometer Views."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from PyQt6.QtWidgets import (
|
||||||
from PyQt6.QtWidgets import QWidget, QLabel, QLineEdit, QHBoxLayout, QSizePolicy, QSpacerItem, QVBoxLayout, QCheckBox, QComboBox
|
QWidget,
|
||||||
from PyQt6.QtGui import QIcon
|
QLabel,
|
||||||
from PyQt6.QtCore import Qt, pyqtSlot
|
QHBoxLayout,
|
||||||
|
QSizePolicy,
|
||||||
|
QSpacerItem,
|
||||||
|
QVBoxLayout,
|
||||||
|
)
|
||||||
from nqrduck.module.module_view import ModuleView
|
from nqrduck.module.module_view import ModuleView
|
||||||
from nqrduck.assets.icons import Logos
|
from nqrduck.assets.icons import Logos
|
||||||
from .settings import FloatSetting, IntSetting, BooleanSetting, SelectionSetting, StringSetting
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -14,13 +19,16 @@ class BaseSpectrometerView(ModuleView):
|
||||||
"""The View Class for all Spectrometers."""
|
"""The View Class for all Spectrometers."""
|
||||||
|
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
|
"""Initializes the spectrometer view."""
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
|
||||||
def load_settings_ui(self) -> None:
|
def load_settings_ui(self) -> None:
|
||||||
"""This method automatically generates a view for the settings of the module.
|
"""This method automatically generates a view for the settings of the module.
|
||||||
If there is a widget file that has been generated by Qt Designer, it will be used. Otherwise, a default view will be generated."""
|
|
||||||
|
|
||||||
|
If there is a widget file that has been generated by Qt Designer, it will be used. Otherwise, a default view will be generated.
|
||||||
|
"""
|
||||||
from .base_spectrometer_widget import Ui_Form
|
from .base_spectrometer_widget import Ui_Form
|
||||||
|
|
||||||
widget = QWidget()
|
widget = QWidget()
|
||||||
widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||||
self._ui_form = Ui_Form()
|
self._ui_form = Ui_Form()
|
||||||
|
@ -59,7 +67,6 @@ class BaseSpectrometerView(ModuleView):
|
||||||
# Add a icon that can be used as a tooltip
|
# Add a icon that can be used as a tooltip
|
||||||
if setting.description is not None:
|
if setting.description is not None:
|
||||||
logger.debug("Adding tooltip to setting: %s", setting.name)
|
logger.debug("Adding tooltip to setting: %s", setting.name)
|
||||||
self_path = Path(__file__).parent
|
|
||||||
icon = Logos.QuestionMark_16x16()
|
icon = Logos.QuestionMark_16x16()
|
||||||
icon_label = QLabel()
|
icon_label = QLabel()
|
||||||
icon_label.setPixmap(icon.pixmap(icon.availableSizes()[0]))
|
icon_label.setPixmap(icon.pixmap(icon.availableSizes()[0]))
|
||||||
|
@ -81,8 +88,5 @@ class BaseSpectrometerView(ModuleView):
|
||||||
category_layout.addStretch(1)
|
category_layout.addStretch(1)
|
||||||
self._ui_form.gridLayout.addLayout(category_layout, row, column)
|
self._ui_form.gridLayout.addLayout(category_layout, row, column)
|
||||||
|
|
||||||
|
|
||||||
# Push all the settings to the top of the widget
|
# Push all the settings to the top of the widget
|
||||||
self._ui_form.verticalLayout.addStretch(1)
|
self._ui_form.verticalLayout.addStretch(1)
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
# run again. Do not edit this file unless you know what you are doing.
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
|
||||||
|
|
||||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
from PyQt6 import QtCore, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
class Ui_Form(object):
|
class Ui_Form:
|
||||||
def setupUi(self, Form):
|
def setupUi(self, Form):
|
||||||
Form.setObjectName("Form")
|
Form.setObjectName("Form")
|
||||||
Form.resize(800, 647)
|
Form.resize(800, 647)
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
"""The Controller for the Spectrometer Module.
|
||||||
|
|
||||||
|
Careful - this is not the base class for the spectrometer submodules, but the controller for the spectrometer module itself.
|
||||||
|
"""
|
||||||
|
|
||||||
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.core.main_controller import MainController
|
from nqrduck.core.main_controller import MainController
|
||||||
from nqrduck_spectrometer.base_spectrometer import BaseSpectrometer
|
from nqrduck_spectrometer.base_spectrometer import BaseSpectrometer
|
||||||
|
@ -40,6 +44,7 @@ class SpectrometerController(ModuleController):
|
||||||
|
|
||||||
def process_signals(self, key: str, value: object) -> None:
|
def process_signals(self, key: str, value: object) -> None:
|
||||||
"""This method processes the signals from the nqrduck module.
|
"""This method processes the signals from the nqrduck module.
|
||||||
|
|
||||||
It is called by the nqrduck module when a signal is emitted.
|
It is called by the nqrduck module when a signal is emitted.
|
||||||
It then calls the corresponding method of the spectrometer model.
|
It then calls the corresponding method of the spectrometer model.
|
||||||
|
|
||||||
|
@ -59,6 +64,7 @@ class SpectrometerController(ModuleController):
|
||||||
|
|
||||||
def on_loading(self) -> None:
|
def on_loading(self) -> None:
|
||||||
"""This method is called when the module is loaded.
|
"""This method is called when the module is loaded.
|
||||||
|
|
||||||
It connects the signals from the spectrometer model to the view.
|
It connects the signals from the spectrometer model to the view.
|
||||||
"""
|
"""
|
||||||
self._module.model.spectrometer_added.connect(
|
self._module.model.spectrometer_added.connect(
|
||||||
|
@ -71,6 +77,7 @@ class SpectrometerController(ModuleController):
|
||||||
|
|
||||||
def on_measurement_start(self) -> None:
|
def on_measurement_start(self) -> None:
|
||||||
"""This method is called when a measurement is started.
|
"""This method is called when a measurement is started.
|
||||||
|
|
||||||
It calls the on_measurement_start method of the active spectrometer.
|
It calls the on_measurement_start method of the active spectrometer.
|
||||||
"""
|
"""
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
|
|
@ -1,14 +1,25 @@
|
||||||
|
"""Class for handling measurement data."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from nqrduck.helpers.signalprocessing import SignalProcessing as sp
|
from nqrduck.helpers.signalprocessing import SignalProcessing as sp
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Measurement():
|
|
||||||
|
class Measurement:
|
||||||
"""This class defines how measurement data should look.
|
"""This class defines how measurement data should look.
|
||||||
|
|
||||||
It includes pulse parameters necessary for further signal processing.
|
It includes pulse parameters necessary for further signal processing.
|
||||||
Every spectrometer should adhere to this data structure in order to be compatible with the rest of the nqrduck.
|
Every spectrometer should adhere to this data structure in order to be compatible with the rest of the nqrduck.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tdx (np.array): Time axis for the x axis of the measurement data.
|
||||||
|
tdy (np.array): Time axis for the y axis of the measurement data.
|
||||||
|
target_frequency (float): Target frequency of the measurement.
|
||||||
|
frequency_shift (float, optional): Frequency shift of the measurement. Defaults to 0.
|
||||||
|
IF_frequency (float, optional): Intermediate frequency of the measurement. Defaults to 0.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
tdx (np.array): Time axis for the x axis of the measurement data.
|
tdx (np.array): Time axis for the x axis of the measurement data.
|
||||||
tdy (np.array): Time axis for the y axis of the measurement data.
|
tdy (np.array): Time axis for the y axis of the measurement data.
|
||||||
|
@ -19,7 +30,15 @@ class Measurement():
|
||||||
yf (np.array): Frequency axis for the y axis of the measurement data.
|
yf (np.array): Frequency axis for the y axis of the measurement data.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, tdx, tdy, target_frequency, frequency_shift : float = 0, IF_frequency : float = 0) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
tdx,
|
||||||
|
tdy,
|
||||||
|
target_frequency,
|
||||||
|
frequency_shift: float = 0,
|
||||||
|
IF_frequency: float = 0,
|
||||||
|
) -> None:
|
||||||
|
"""Initializes the measurement."""
|
||||||
self.tdx = tdx
|
self.tdx = tdx
|
||||||
self.tdy = tdy
|
self.tdy = tdy
|
||||||
self.target_frequency = target_frequency
|
self.target_frequency = target_frequency
|
||||||
|
@ -32,31 +51,33 @@ class Measurement():
|
||||||
"""Converts the measurement to a json-compatible format.
|
"""Converts the measurement to a json-compatible format.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict -- The measurement in json-compatible format.
|
dict : The measurement in json-compatible format.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
"tdx": self.tdx.tolist(),
|
"tdx": self.tdx.tolist(),
|
||||||
"tdy": [[x.real, x.imag] for x in self.tdy], # Convert complex numbers to list
|
"tdy": [
|
||||||
|
[x.real, x.imag] for x in self.tdy
|
||||||
|
], # Convert complex numbers to list
|
||||||
"target_frequency": self.target_frequency,
|
"target_frequency": self.target_frequency,
|
||||||
"IF_frequency": self.IF_frequency
|
"IF_frequency": self.IF_frequency,
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, json):
|
def from_json(cls, json: dict):
|
||||||
"""Converts the json format to a measurement.
|
"""Converts the json format to a measurement.
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
json (dict) -- The measurement in json-compatible format.
|
json (dict) : The measurement in json-compatible format.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Measurement -- The measurement.
|
Measurement : The measurement.
|
||||||
"""
|
"""
|
||||||
tdy = np.array([complex(y[0], y[1]) for y in json["tdy"]])
|
tdy = np.array([complex(y[0], y[1]) for y in json["tdy"]])
|
||||||
return cls(
|
return cls(
|
||||||
np.array(json["tdx"]),
|
np.array(json["tdx"]),
|
||||||
tdy,
|
tdy,
|
||||||
target_frequency=json["target_frequency"],
|
target_frequency=json["target_frequency"],
|
||||||
IF_frequency = json["IF_frequency"]
|
IF_frequency=json["IF_frequency"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Measurement data
|
# Measurement data
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""The model for the nqrduck-spectrometer module. This module is responsible for managing the spectrometers."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from PyQt6.QtCore import pyqtSignal
|
from PyQt6.QtCore import pyqtSignal
|
||||||
from nqrduck.module.module_model import ModuleModel
|
from nqrduck.module.module_model import ModuleModel
|
||||||
|
@ -5,19 +7,36 @@ from .base_spectrometer import BaseSpectrometer
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SpectrometerModel(ModuleModel):
|
class SpectrometerModel(ModuleModel):
|
||||||
|
"""The model for the spectrometer module.
|
||||||
|
|
||||||
|
This class is responsible for managing the spectrometers.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
module (Module) : The module that the spectrometer is connected to
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
active_spectrometer (BaseSpectrometer) : The currently active spectrometer
|
||||||
|
available_spectrometers (dict) : A dictionary of all available spectrometers
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
spectrometer_added (BaseSpectrometer) : Signal emitted when a spectrometer is added
|
||||||
|
active_spectrometer_changed (BaseSpectrometer) : Signal emitted when the active spectrometer is changed
|
||||||
|
"""
|
||||||
|
|
||||||
spectrometer_added = pyqtSignal(BaseSpectrometer)
|
spectrometer_added = pyqtSignal(BaseSpectrometer)
|
||||||
active_spectrometer_changed = pyqtSignal(BaseSpectrometer)
|
active_spectrometer_changed = pyqtSignal(BaseSpectrometer)
|
||||||
|
|
||||||
def __init__(self, module) -> None:
|
def __init__(self, module) -> None:
|
||||||
|
"""Initializes the spectrometer model."""
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
self._active_spectrometer = None
|
self._active_spectrometer = None
|
||||||
self._available_spectrometers = dict()
|
self._available_spectrometers = dict()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def active_spectrometer(self):
|
def active_spectrometer(self):
|
||||||
"""The currently active spectrometer. This is the one that is currently being used.
|
"""The currently active spectrometer. This is the one that is currently being used."""
|
||||||
"""
|
|
||||||
return self._active_spectrometer
|
return self._active_spectrometer
|
||||||
|
|
||||||
@active_spectrometer.setter
|
@active_spectrometer.setter
|
||||||
|
@ -26,19 +45,24 @@ class SpectrometerModel(ModuleModel):
|
||||||
self.active_spectrometer_changed.emit(value)
|
self.active_spectrometer_changed.emit(value)
|
||||||
spectrometer_module_name = value.model.toolbar_name
|
spectrometer_module_name = value.model.toolbar_name
|
||||||
logger.debug("Active spectrometer changed to %s", spectrometer_module_name)
|
logger.debug("Active spectrometer changed to %s", spectrometer_module_name)
|
||||||
self.module.nqrduck_signal.emit("active_spectrometer_changed", spectrometer_module_name)
|
self.module.nqrduck_signal.emit(
|
||||||
|
"active_spectrometer_changed", spectrometer_module_name
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available_spectrometers(self):
|
def available_spectrometers(self):
|
||||||
"""A dictionary of all available spectrometers. The key is the name of the spectrometer and the value is the module.
|
"""A dictionary of all available spectrometers. The key is the name of the spectrometer and the value is the module."""
|
||||||
"""
|
|
||||||
return self._available_spectrometers
|
return self._available_spectrometers
|
||||||
|
|
||||||
def add_spectrometers(self, spectrometer_module_name, module):
|
def add_spectrometers(self, spectrometer_module_name, module):
|
||||||
|
"""Adds a spectrometer to the available spectrometers.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
spectrometer_module_name (str) : The name of the spectrometer
|
||||||
|
module (BaseSpectrometer) : The module of the spectrometer
|
||||||
|
"""
|
||||||
self._available_spectrometers[spectrometer_module_name] = module
|
self._available_spectrometers[spectrometer_module_name] = module
|
||||||
logger.debug("Added module: %s", spectrometer_module_name)
|
logger.debug("Added module: %s", spectrometer_module_name)
|
||||||
self.spectrometer_added.emit(module)
|
self.spectrometer_added.emit(module)
|
||||||
self.active_spectrometer = module
|
self.active_spectrometer = module
|
||||||
self.add_submodule(spectrometer_module_name)
|
self.add_submodule(spectrometer_module_name)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
|
"""Contains the classes for the pulse parameters of the spectrometer. It includes the functions and the options for the pulse parameters.
|
||||||
|
|
||||||
|
Todo:
|
||||||
|
* This shouldn't be in the spectrometer module. It should be in it"s own pulse sequence module.
|
||||||
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import logging
|
import logging
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import sympy
|
import sympy
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from pathlib import Path
|
|
||||||
from PyQt6.QtGui import QPixmap
|
from PyQt6.QtGui import QPixmap
|
||||||
from nqrduck.contrib.mplwidget import MplWidget
|
from nqrduck.contrib.mplwidget import MplWidget
|
||||||
from nqrduck.helpers.signalprocessing import SignalProcessing as sp
|
from nqrduck.helpers.signalprocessing import SignalProcessing as sp
|
||||||
|
@ -14,6 +19,22 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Function:
|
class Function:
|
||||||
|
"""A function that can be used as a pulse parameter.
|
||||||
|
|
||||||
|
This class is the base class for all functions that can be used as pulse parameters. Functions can be used for pulse shapes, for example.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
expr (str | sympy.Expr): The expression of the function.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (str): The name of the function.
|
||||||
|
parameters (list): The parameters of the function.
|
||||||
|
expr (sympy.Expr): The sympy expression of the function.
|
||||||
|
resolution (Decimal): The resolution of the function in seconds.
|
||||||
|
start_x (float): The x value where the evalution of the function starts.
|
||||||
|
end_x (float): The x value where the evalution of the function ends.
|
||||||
|
"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
parameters: list
|
parameters: list
|
||||||
expression: str | sympy.Expr
|
expression: str | sympy.Expr
|
||||||
|
@ -22,6 +43,7 @@ class Function:
|
||||||
end_x: float
|
end_x: float
|
||||||
|
|
||||||
def __init__(self, expr) -> None:
|
def __init__(self, expr) -> None:
|
||||||
|
"""Initializes the function."""
|
||||||
self.parameters = []
|
self.parameters = []
|
||||||
self.expr = expr
|
self.expr = expr
|
||||||
self.resolution = Decimal(1 / 30.72e6)
|
self.resolution = Decimal(1 / 30.72e6)
|
||||||
|
@ -121,7 +143,9 @@ class Function:
|
||||||
mpl_widget.canvas.ax.grid(True)
|
mpl_widget.canvas.ax.grid(True)
|
||||||
return mpl_widget
|
return mpl_widget
|
||||||
|
|
||||||
def get_pulse_amplitude(self, pulse_length: Decimal, resolution : Decimal = None) -> np.array:
|
def get_pulse_amplitude(
|
||||||
|
self, pulse_length: Decimal, resolution: Decimal = None
|
||||||
|
) -> np.array:
|
||||||
"""Returns the pulse amplitude in the time domain.
|
"""Returns the pulse amplitude in the time domain.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -133,11 +157,12 @@ class Function:
|
||||||
"""
|
"""
|
||||||
return self.evaluate(pulse_length, resolution=resolution)
|
return self.evaluate(pulse_length, resolution=resolution)
|
||||||
|
|
||||||
def add_parameter(self, parameter: "Function.Parameter") -> None:
|
def add_parameter(self, parameter: Function.Parameter) -> None:
|
||||||
"""Adds a parameter to the function.
|
"""Adds a parameter to the function.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
parameter (Function.Parameter): The parameter to add."""
|
parameter (Function.Parameter): The parameter to add.
|
||||||
|
"""
|
||||||
self.parameters.append(parameter)
|
self.parameters.append(parameter)
|
||||||
|
|
||||||
def to_json(self) -> dict:
|
def to_json(self) -> dict:
|
||||||
|
@ -156,7 +181,7 @@ class Function:
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, data: dict) -> "Function":
|
def from_json(cls, data: dict) -> Function:
|
||||||
"""Creates a function from a json representation.
|
"""Creates a function from a json representation.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -193,7 +218,7 @@ class Function:
|
||||||
if isinstance(expr, str):
|
if isinstance(expr, str):
|
||||||
try:
|
try:
|
||||||
self._expr = sympy.sympify(expr)
|
self._expr = sympy.sympify(expr)
|
||||||
except:
|
except ValueError:
|
||||||
logger.error("Could not convert %s to a sympy expression", expr)
|
logger.error("Could not convert %s to a sympy expression", expr)
|
||||||
raise SyntaxError("Could not convert %s to a sympy expression" % expr)
|
raise SyntaxError("Could not convert %s to a sympy expression" % expr)
|
||||||
elif isinstance(expr, sympy.Expr):
|
elif isinstance(expr, sympy.Expr):
|
||||||
|
@ -208,7 +233,7 @@ class Function:
|
||||||
def resolution(self, resolution):
|
def resolution(self, resolution):
|
||||||
try:
|
try:
|
||||||
self._resolution = Decimal(resolution)
|
self._resolution = Decimal(resolution)
|
||||||
except:
|
except ValueError:
|
||||||
logger.error("Could not convert %s to a decimal", resolution)
|
logger.error("Could not convert %s to a decimal", resolution)
|
||||||
raise SyntaxError("Could not convert %s to a decimal" % resolution)
|
raise SyntaxError("Could not convert %s to a decimal" % resolution)
|
||||||
|
|
||||||
|
@ -221,7 +246,7 @@ class Function:
|
||||||
def start_x(self, start_x):
|
def start_x(self, start_x):
|
||||||
try:
|
try:
|
||||||
self._start_x = float(start_x)
|
self._start_x = float(start_x)
|
||||||
except:
|
except ValueError:
|
||||||
logger.error("Could not convert %s to a float", start_x)
|
logger.error("Could not convert %s to a float", start_x)
|
||||||
raise SyntaxError("Could not convert %s to a float" % start_x)
|
raise SyntaxError("Could not convert %s to a float" % start_x)
|
||||||
|
|
||||||
|
@ -234,7 +259,7 @@ class Function:
|
||||||
def end_x(self, end_x):
|
def end_x(self, end_x):
|
||||||
try:
|
try:
|
||||||
self._end_x = float(end_x)
|
self._end_x = float(end_x)
|
||||||
except:
|
except ValueError:
|
||||||
logger.error("Could not convert %s to a float", end_x)
|
logger.error("Could not convert %s to a float", end_x)
|
||||||
raise SyntaxError("Could not convert %s to a float" % end_x)
|
raise SyntaxError("Could not convert %s to a float" % end_x)
|
||||||
|
|
||||||
|
@ -242,12 +267,30 @@ class Function:
|
||||||
"""This is the default pixmap for every function. If one wants to have a custom pixmap, this method has to be overwritten.
|
"""This is the default pixmap for every function. If one wants to have a custom pixmap, this method has to be overwritten.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
QPixmap -- The default pixmap for every function"""
|
QPixmap : The default pixmap for every function
|
||||||
|
"""
|
||||||
pixmap = PulseParamters.TXCustom()
|
pixmap = PulseParamters.TXCustom()
|
||||||
return pixmap
|
return pixmap
|
||||||
|
|
||||||
class Parameter:
|
class Parameter:
|
||||||
|
"""A parameter of a function.
|
||||||
|
|
||||||
|
This can be for example the standard deviation of a Gaussian function.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the parameter.
|
||||||
|
symbol (str): The symbol of the parameter.
|
||||||
|
value (float): The value of the parameter.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (str): The name of the parameter.
|
||||||
|
symbol (str): The symbol of the parameter.
|
||||||
|
value (float): The value of the parameter.
|
||||||
|
default (float): The default value of the parameter.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, symbol: str, value: float) -> None:
|
def __init__(self, name: str, symbol: str, value: float) -> None:
|
||||||
|
"""Initializes the parameter."""
|
||||||
self.name = name
|
self.name = name
|
||||||
self.symbol = symbol
|
self.symbol = symbol
|
||||||
self.value = value
|
self.value = value
|
||||||
|
@ -296,20 +339,31 @@ class RectFunction(Function):
|
||||||
name = "Rectangular"
|
name = "Rectangular"
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
"""Initializes the RecFunction."""
|
||||||
expr = sympy.sympify("1")
|
expr = sympy.sympify("1")
|
||||||
super().__init__(expr)
|
super().__init__(expr)
|
||||||
|
|
||||||
def get_pixmap(self):
|
def get_pixmap(self) -> QPixmap:
|
||||||
|
"""Returns the pixmap of the rectangular function.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
QPixmap: The pixmap of the rectangular function.
|
||||||
|
"""
|
||||||
pixmap = PulseParamters.TXRect()
|
pixmap = PulseParamters.TXRect()
|
||||||
return pixmap
|
return pixmap
|
||||||
|
|
||||||
|
|
||||||
class SincFunction(Function):
|
class SincFunction(Function):
|
||||||
"""The sinc function."""
|
"""The sinc function.
|
||||||
|
|
||||||
|
The sinc function is defined as sin(x * l) / (x * l).
|
||||||
|
The parameter is the scale factor l.
|
||||||
|
"""
|
||||||
|
|
||||||
name = "Sinc"
|
name = "Sinc"
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
"""Initializes the SincFunction."""
|
||||||
expr = sympy.sympify("sin(x * l)/ (x * l)")
|
expr = sympy.sympify("sin(x * l)/ (x * l)")
|
||||||
super().__init__(expr)
|
super().__init__(expr)
|
||||||
self.add_parameter(Function.Parameter("Scale Factor", "l", 2))
|
self.add_parameter(Function.Parameter("Scale Factor", "l", 2))
|
||||||
|
@ -317,16 +371,26 @@ class SincFunction(Function):
|
||||||
self.end_x = np.pi
|
self.end_x = np.pi
|
||||||
|
|
||||||
def get_pixmap(self):
|
def get_pixmap(self):
|
||||||
|
"""Returns the pixmap of the sinc function.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
QPixmap: The pixmap of the sinc function.
|
||||||
|
"""
|
||||||
pixmap = PulseParamters.TXSinc()
|
pixmap = PulseParamters.TXSinc()
|
||||||
return pixmap
|
return pixmap
|
||||||
|
|
||||||
|
|
||||||
class GaussianFunction(Function):
|
class GaussianFunction(Function):
|
||||||
"""The Gaussian function."""
|
"""The Gaussian function.
|
||||||
|
|
||||||
|
The Gaussian function is defined as exp(-0.5 * ((x - mu) / sigma)**2).
|
||||||
|
The parameters are the mean and the standard deviation.
|
||||||
|
"""
|
||||||
|
|
||||||
name = "Gaussian"
|
name = "Gaussian"
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
"""Initializes the GaussianFunction."""
|
||||||
expr = sympy.sympify("exp(-0.5 * ((x - mu) / sigma)**2)")
|
expr = sympy.sympify("exp(-0.5 * ((x - mu) / sigma)**2)")
|
||||||
super().__init__(expr)
|
super().__init__(expr)
|
||||||
self.add_parameter(Function.Parameter("Mean", "mu", 0))
|
self.add_parameter(Function.Parameter("Mean", "mu", 0))
|
||||||
|
@ -335,6 +399,11 @@ class GaussianFunction(Function):
|
||||||
self.end_x = np.pi
|
self.end_x = np.pi
|
||||||
|
|
||||||
def get_pixmap(self):
|
def get_pixmap(self):
|
||||||
|
"""Returns the QPixmap of the Gaussian function.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
QPixmap: The QPixmap of the Gaussian function.
|
||||||
|
"""
|
||||||
pixmap = PulseParamters.TXGauss()
|
pixmap = PulseParamters.TXGauss()
|
||||||
return pixmap
|
return pixmap
|
||||||
|
|
||||||
|
@ -351,25 +420,55 @@ class CustomFunction(Function):
|
||||||
name = "Custom"
|
name = "Custom"
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
"""Initializes the Custom Function."""
|
||||||
expr = sympy.sympify(" 2 * x**2 + 3 * x + 1")
|
expr = sympy.sympify(" 2 * x**2 + 3 * x + 1")
|
||||||
super().__init__(expr)
|
super().__init__(expr)
|
||||||
|
|
||||||
|
|
||||||
class Option:
|
class Option:
|
||||||
"""Defines options for the pulse parameters which can then be set accordingly."""
|
"""Defines options for the pulse parameters which can then be set accordingly.
|
||||||
|
|
||||||
|
Options can be of different types, for example boolean, numeric or function.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the option.
|
||||||
|
value: The value of the option.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (str): The name of the option.
|
||||||
|
value: The value of the option.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, value) -> None:
|
def __init__(self, name: str, value) -> None:
|
||||||
|
"""Initializes the option."""
|
||||||
self.name = name
|
self.name = name
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def set_value(self):
|
def set_value(self):
|
||||||
|
"""Sets the value of the option.
|
||||||
|
|
||||||
|
This method has to be implemented in the derived classes.
|
||||||
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
|
"""Returns a json representation of the option.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: The json representation of the option.
|
||||||
|
"""
|
||||||
return {"name": self.name, "value": self.value, "type": self.TYPE}
|
return {"name": self.name, "value": self.value, "type": self.TYPE}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, data) -> "Option":
|
def from_json(cls, data) -> Option:
|
||||||
|
"""Creates an option from a json representation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (dict): The json representation of the option.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Option: The option.
|
||||||
|
"""
|
||||||
for subclass in cls.__subclasses__():
|
for subclass in cls.__subclasses__():
|
||||||
if subclass.TYPE == data["type"]:
|
if subclass.TYPE == data["type"]:
|
||||||
cls = subclass
|
cls = subclass
|
||||||
|
@ -390,6 +489,7 @@ class BooleanOption(Option):
|
||||||
TYPE = "Boolean"
|
TYPE = "Boolean"
|
||||||
|
|
||||||
def set_value(self, value):
|
def set_value(self, value):
|
||||||
|
"""Sets the value of the option."""
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
|
|
||||||
|
@ -399,49 +499,102 @@ class NumericOption(Option):
|
||||||
TYPE = "Numeric"
|
TYPE = "Numeric"
|
||||||
|
|
||||||
def set_value(self, value):
|
def set_value(self, value):
|
||||||
|
"""Sets the value of the option."""
|
||||||
self.value = float(value)
|
self.value = float(value)
|
||||||
|
|
||||||
|
|
||||||
class FunctionOption(Option):
|
class FunctionOption(Option):
|
||||||
"""Defines a selection option for a pulse parameter option.
|
"""Defines a selection option for a pulse parameter option.
|
||||||
It takes different function objects."""
|
|
||||||
|
It takes different function objects.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the option.
|
||||||
|
functions (list): The functions that can be selected.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (str): The name of the option.
|
||||||
|
functions (list): The functions that can be selected.
|
||||||
|
"""
|
||||||
|
|
||||||
TYPE = "Function"
|
TYPE = "Function"
|
||||||
|
|
||||||
def __init__(self, name, functions) -> None:
|
def __init__(self, name, functions) -> None:
|
||||||
|
"""Initializes the FunctionOption."""
|
||||||
super().__init__(name, functions[0])
|
super().__init__(name, functions[0])
|
||||||
self.functions = functions
|
self.functions = functions
|
||||||
|
|
||||||
def set_value(self, value):
|
def set_value(self, value):
|
||||||
|
"""Sets the value of the option.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The value of the option.
|
||||||
|
"""
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def get_function_by_name(self, name):
|
def get_function_by_name(self, name):
|
||||||
|
"""Returns the function with the given name.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the function.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Function: The function with the given name.
|
||||||
|
"""
|
||||||
for function in self.functions:
|
for function in self.functions:
|
||||||
if function.name == name:
|
if function.name == name:
|
||||||
return function
|
return function
|
||||||
raise ValueError("Function with name %s not found" % name)
|
raise ValueError("Function with name %s not found" % name)
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
|
"""Returns a json representation of the option.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: The json representation of the option.
|
||||||
|
"""
|
||||||
return {"name": self.name, "value": self.value.to_json(), "type": self.TYPE}
|
return {"name": self.name, "value": self.value.to_json(), "type": self.TYPE}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, data):
|
def from_json(cls, data):
|
||||||
|
"""Creates a FunctionOption from a json representation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (dict): The json representation of the FunctionOption.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
FunctionOption: The FunctionOption.
|
||||||
|
"""
|
||||||
functions = [function() for function in Function.__subclasses__()]
|
functions = [function() for function in Function.__subclasses__()]
|
||||||
obj = cls(data["name"], functions)
|
obj = cls(data["name"], functions)
|
||||||
obj.value = Function.from_json(data["value"])
|
obj.value = Function.from_json(data["value"])
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def get_pixmap(self):
|
def get_pixmap(self):
|
||||||
|
"""Returns the pixmap of the function."""
|
||||||
return self.value.get_pixmap()
|
return self.value.get_pixmap()
|
||||||
|
|
||||||
|
|
||||||
class TXPulse(BaseSpectrometerModel.PulseParameter):
|
class TXPulse(BaseSpectrometerModel.PulseParameter):
|
||||||
""" Basic TX Pulse Parameter. It includes options for the relative amplitude, the phase and the pulse shape."""
|
"""Basic TX Pulse Parameter. It includes options for the relative amplitude, the phase and the pulse shape.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the pulse parameter.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
RELATIVE_AMPLITUDE (str): The relative amplitude of the pulse.
|
||||||
|
TX_PHASE (str): The phase of the pulse.
|
||||||
|
TX_PULSE_SHAPE (str): The pulse shape.
|
||||||
|
"""
|
||||||
|
|
||||||
RELATIVE_AMPLITUDE = "Relative TX Amplitude"
|
RELATIVE_AMPLITUDE = "Relative TX Amplitude"
|
||||||
TX_PHASE = "TX Phase"
|
TX_PHASE = "TX Phase"
|
||||||
TX_PULSE_SHAPE = "TX Pulse Shape"
|
TX_PULSE_SHAPE = "TX Pulse Shape"
|
||||||
|
|
||||||
def __init__(self, name) -> None:
|
def __init__(self, name) -> None:
|
||||||
|
"""Initializes the TX Pulse Parameter.
|
||||||
|
|
||||||
|
It adds the options for the relative amplitude, the phase and the pulse shape.
|
||||||
|
"""
|
||||||
super().__init__(name)
|
super().__init__(name)
|
||||||
self.add_option(NumericOption(self.RELATIVE_AMPLITUDE, 0))
|
self.add_option(NumericOption(self.RELATIVE_AMPLITUDE, 0))
|
||||||
self.add_option(NumericOption(self.TX_PHASE, 0))
|
self.add_option(NumericOption(self.TX_PHASE, 0))
|
||||||
|
@ -453,6 +606,11 @@ class TXPulse(BaseSpectrometerModel.PulseParameter):
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_pixmap(self):
|
def get_pixmap(self):
|
||||||
|
"""Returns the pixmap of the TX Pulse Parameter.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
QPixmap: The pixmap of the TX Pulse Parameter depending on the relative amplitude.
|
||||||
|
"""
|
||||||
if self.get_option_by_name(self.RELATIVE_AMPLITUDE).value > 0:
|
if self.get_option_by_name(self.RELATIVE_AMPLITUDE).value > 0:
|
||||||
return self.get_option_by_name(self.TX_PULSE_SHAPE).get_pixmap()
|
return self.get_option_by_name(self.TX_PULSE_SHAPE).get_pixmap()
|
||||||
else:
|
else:
|
||||||
|
@ -461,15 +619,32 @@ class TXPulse(BaseSpectrometerModel.PulseParameter):
|
||||||
|
|
||||||
|
|
||||||
class RXReadout(BaseSpectrometerModel.PulseParameter):
|
class RXReadout(BaseSpectrometerModel.PulseParameter):
|
||||||
"""Basic PulseParameter for the RX Readout. It includes an option for the RX Readout state."""
|
"""Basic PulseParameter for the RX Readout. It includes an option for the RX Readout state.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the pulse parameter.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
RX (str): The RX Readout state.
|
||||||
|
"""
|
||||||
|
|
||||||
RX = "RX"
|
RX = "RX"
|
||||||
|
|
||||||
def __init__(self, name) -> None:
|
def __init__(self, name) -> None:
|
||||||
|
"""Initializes the RX Readout PulseParameter.
|
||||||
|
|
||||||
|
It adds an option for the RX Readout state.
|
||||||
|
"""
|
||||||
super().__init__(name)
|
super().__init__(name)
|
||||||
self.add_option(BooleanOption(self.RX, False))
|
self.add_option(BooleanOption(self.RX, False))
|
||||||
|
|
||||||
def get_pixmap(self):
|
def get_pixmap(self):
|
||||||
if self.get_option_by_name(self.RX).value == False:
|
"""Returns the pixmap of the RX Readout PulseParameter.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
QPixmap: The pixmap of the RX Readout PulseParameter depending on the RX Readout state.
|
||||||
|
"""
|
||||||
|
if self.get_option_by_name(self.RX).value is False:
|
||||||
pixmap = PulseParamters.RXOff()
|
pixmap = PulseParamters.RXOff()
|
||||||
else:
|
else:
|
||||||
pixmap = PulseParamters.RXOn()
|
pixmap = PulseParamters.RXOn()
|
||||||
|
@ -477,14 +652,32 @@ class RXReadout(BaseSpectrometerModel.PulseParameter):
|
||||||
|
|
||||||
|
|
||||||
class Gate(BaseSpectrometerModel.PulseParameter):
|
class Gate(BaseSpectrometerModel.PulseParameter):
|
||||||
|
"""Basic PulseParameter for the Gate. It includes an option for the Gate state.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the pulse parameter.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
GATE_STATE (str): The Gate state.
|
||||||
|
"""
|
||||||
|
|
||||||
GATE_STATE = "Gate State"
|
GATE_STATE = "Gate State"
|
||||||
|
|
||||||
def __init__(self, name) -> None:
|
def __init__(self, name) -> None:
|
||||||
|
"""Initializes the Gate PulseParameter.
|
||||||
|
|
||||||
|
It adds an option for the Gate state.
|
||||||
|
"""
|
||||||
super().__init__(name)
|
super().__init__(name)
|
||||||
self.add_option(BooleanOption(self.GATE_STATE, False))
|
self.add_option(BooleanOption(self.GATE_STATE, False))
|
||||||
|
|
||||||
def get_pixmap(self):
|
def get_pixmap(self):
|
||||||
if self.get_option_by_name(self.GATE_STATE).value == False:
|
"""Returns the pixmap of the Gate PulseParameter.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
QPixmap: The pixmap of the Gate PulseParameter depending on the Gate state.
|
||||||
|
"""
|
||||||
|
if self.get_option_by_name(self.GATE_STATE).value is False:
|
||||||
pixmap = PulseParamters.GateOff()
|
pixmap = PulseParamters.GateOff()
|
||||||
else:
|
else:
|
||||||
pixmap = PulseParamters.GateOn()
|
pixmap = PulseParamters.GateOn()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""Contains the PulseSequence class that is used to store a pulse sequence and its events."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from nqrduck.helpers.unitconverter import UnitConverter
|
from nqrduck.helpers.unitconverter import UnitConverter
|
||||||
|
@ -7,34 +9,70 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PulseSequence:
|
class PulseSequence:
|
||||||
"""A pulse sequence is a collection of events that are executed in a certain order."""
|
"""A pulse sequence is a collection of events that are executed in a certain order.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the pulse sequence
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (str): The name of the pulse sequence
|
||||||
|
events (list): The events of the pulse sequence
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, name) -> None:
|
def __init__(self, name) -> None:
|
||||||
|
"""Initializes the pulse sequence."""
|
||||||
self.name = name
|
self.name = name
|
||||||
self.events = list()
|
self.events = list()
|
||||||
|
|
||||||
def get_event_names(self) -> list:
|
def get_event_names(self) -> list:
|
||||||
|
"""Returns a list of the names of the events in the pulse sequence.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: The names of the events
|
||||||
|
"""
|
||||||
return [event.name for event in self.events]
|
return [event.name for event in self.events]
|
||||||
|
|
||||||
class Event:
|
class Event:
|
||||||
"""An event is a part of a pulse sequence. It has a name and a duration and different parameters that have to be set."""
|
"""An event is a part of a pulse sequence. It has a name and a duration and different parameters that have to be set.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the event
|
||||||
|
duration (str): The duration of the event
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (str): The name of the event
|
||||||
|
duration (str): The duration of the event
|
||||||
|
parameters (OrderedDict): The parameters of the event
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, duration: str) -> None:
|
def __init__(self, name: str, duration: str) -> None:
|
||||||
|
"""Initializes the event."""
|
||||||
self.parameters = OrderedDict()
|
self.parameters = OrderedDict()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.duration = duration
|
self.duration = duration
|
||||||
|
|
||||||
def add_parameter(self, parameter) -> None:
|
def add_parameter(self, parameter) -> None:
|
||||||
|
"""Adds a parameter to the event.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
parameter: The parameter to add
|
||||||
|
"""
|
||||||
self.parameters.append(parameter)
|
self.parameters.append(parameter)
|
||||||
|
|
||||||
def on_duration_changed(self, duration: str) -> None:
|
def on_duration_changed(self, duration: str) -> None:
|
||||||
|
"""This method is called when the duration of the event is changed.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
duration (str): The new duration of the event
|
||||||
|
"""
|
||||||
logger.debug("Duration of event %s changed to %s", self.name, duration)
|
logger.debug("Duration of event %s changed to %s", self.name, duration)
|
||||||
self.duration = duration
|
self.duration = duration
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_event(cls, event, pulse_parameter_options):
|
def load_event(cls, event, pulse_parameter_options):
|
||||||
"""
|
"""Loads an event from a dict.
|
||||||
Loads an event from a dict. The pulse paramter options are needed to load the parameters
|
|
||||||
|
The pulse paramter options are needed to load the parameters
|
||||||
and determine if the correct spectrometer is active.
|
and determine if the correct spectrometer is active.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -66,6 +104,7 @@ class PulseSequence:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def duration(self):
|
def duration(self):
|
||||||
|
"""The duration of the event."""
|
||||||
return self._duration
|
return self._duration
|
||||||
|
|
||||||
@duration.setter
|
@duration.setter
|
||||||
|
@ -80,12 +119,12 @@ class PulseSequence:
|
||||||
|
|
||||||
self._duration = duration
|
self._duration = duration
|
||||||
|
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
"""Returns a dict with all the data in the pulse sequence
|
"""Returns a dict with all the data in the pulse sequence.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: The dict with the sequence data"""
|
dict: The dict with the sequence data
|
||||||
|
"""
|
||||||
data = {"name": self.name, "events": []}
|
data = {"name": self.name, "events": []}
|
||||||
for event in self.events:
|
for event in self.events:
|
||||||
event_data = {
|
event_data = {
|
||||||
|
@ -102,7 +141,9 @@ class PulseSequence:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_sequence(cls, sequence, pulse_parameter_options):
|
def load_sequence(cls, sequence, pulse_parameter_options):
|
||||||
"""Loads a pulse sequence from a dict. The pulse paramter options are needed to load the parameters
|
"""Loads a pulse sequence from a dict.
|
||||||
|
|
||||||
|
The pulse paramter options are needed to load the parameters
|
||||||
and make sure the correct spectrometer is active.
|
and make sure the correct spectrometer is active.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -123,13 +164,16 @@ class PulseSequence:
|
||||||
|
|
||||||
class Variable:
|
class Variable:
|
||||||
"""A variable is a parameter that can be used within a pulsesequence as a placeholder.
|
"""A variable is a parameter that can be used within a pulsesequence as a placeholder.
|
||||||
|
|
||||||
For example the event duration a Variable with name a can be set. This variable can then be set to a list of different values.
|
For example the event duration a Variable with name a can be set. This variable can then be set to a list of different values.
|
||||||
On execution of the pulse sequence the event duration will be set to the first value in the list.
|
On execution of the pulse sequence the event duration will be set to the first value in the list.
|
||||||
Then the pulse sequence will be executed with the second value of the list. This is repeated until the pulse sequence has
|
Then the pulse sequence will be executed with the second value of the list. This is repeated until the pulse sequence has
|
||||||
been executed with all values in the list."""
|
been executed with all values in the list.
|
||||||
|
"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
"""The name of the variable."""
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
@name.setter
|
@name.setter
|
||||||
|
@ -140,6 +184,7 @@ class PulseSequence:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def values(self):
|
def values(self):
|
||||||
|
"""The values of the variable. This is a list of values that the variable can take."""
|
||||||
return self._values
|
return self._values
|
||||||
|
|
||||||
@values.setter
|
@values.setter
|
||||||
|
@ -150,10 +195,13 @@ class PulseSequence:
|
||||||
|
|
||||||
class VariableGroup:
|
class VariableGroup:
|
||||||
"""Variables can be grouped together.
|
"""Variables can be grouped together.
|
||||||
If we have groups a and b the pulse sequence will be executed for all combinations of variables in a and b."""
|
|
||||||
|
If we have groups a and b the pulse sequence will be executed for all combinations of variables in a and b.
|
||||||
|
"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
"""The name of the variable group."""
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
@name.setter
|
@name.setter
|
||||||
|
@ -164,6 +212,7 @@ class PulseSequence:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def variables(self):
|
def variables(self):
|
||||||
|
"""The variables in the group. This is a list of variables."""
|
||||||
return self._variables
|
return self._variables
|
||||||
|
|
||||||
@variables.setter
|
@variables.setter
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""Settings for the different spectrometers."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import ipaddress
|
import ipaddress
|
||||||
from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot
|
from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot
|
||||||
|
@ -10,7 +12,20 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Setting(QObject):
|
class Setting(QObject):
|
||||||
"""A setting for the spectrometer is a value that is the same for all events in a pulse sequence.
|
"""A setting for the spectrometer is a value that is the same for all events in a pulse sequence.
|
||||||
E.g. the Transmit gain or the number of points in a spectrum."""
|
|
||||||
|
E.g. the Transmit gain or the number of points in a spectrum.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str) : The name of the setting
|
||||||
|
description (str) : A description of the setting
|
||||||
|
default : The default value of the setting
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (str) : The name of the setting
|
||||||
|
description (str) : A description of the setting
|
||||||
|
value : The value of the setting
|
||||||
|
widget : The widget that is used to change the setting
|
||||||
|
"""
|
||||||
|
|
||||||
settings_changed = pyqtSignal()
|
settings_changed = pyqtSignal()
|
||||||
|
|
||||||
|
@ -20,6 +35,7 @@ class Setting(QObject):
|
||||||
Args:
|
Args:
|
||||||
name (str): The name of the setting.
|
name (str): The name of the setting.
|
||||||
description (str): A description of the setting.
|
description (str): A description of the setting.
|
||||||
|
default: The default value of the setting.
|
||||||
"""
|
"""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -32,21 +48,31 @@ class Setting(QObject):
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def on_value_changed(self, value):
|
def on_value_changed(self, value):
|
||||||
|
"""This method is called when the value of the setting is changed.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value (str): The new value of the setting.
|
||||||
|
"""
|
||||||
logger.debug("Setting %s changed to %s", self.name, value)
|
logger.debug("Setting %s changed to %s", self.name, value)
|
||||||
self.value = value
|
self.value = value
|
||||||
self.settings_changed.emit()
|
self.settings_changed.emit()
|
||||||
|
|
||||||
def get_setting(self):
|
def get_setting(self):
|
||||||
|
"""Return the value of the setting.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The value of the setting.
|
||||||
|
"""
|
||||||
return float(self.value)
|
return float(self.value)
|
||||||
|
|
||||||
def get_widget(self):
|
def get_widget(self):
|
||||||
"""Return a widget for the setting.
|
"""Return a widget for the setting.
|
||||||
|
|
||||||
The default widget is simply a QLineEdit.
|
The default widget is simply a QLineEdit.
|
||||||
This method can be overwritten by subclasses to return a different widget.
|
This method can be overwritten by subclasses to return a different widget.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
QLineEdit: A QLineEdit widget that can be used to change the setting.
|
QLineEdit: A QLineEdit widget that can be used to change the setting.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
widget = QLineEdit(str(self.value))
|
widget = QLineEdit(str(self.value))
|
||||||
widget.setMinimumWidth(100)
|
widget.setMinimumWidth(100)
|
||||||
|
@ -72,7 +98,16 @@ class Setting(QObject):
|
||||||
|
|
||||||
|
|
||||||
class FloatSetting(Setting):
|
class FloatSetting(Setting):
|
||||||
"""A setting that is a Float."""
|
"""A setting that is a Float.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str) : The name of the setting
|
||||||
|
default : The default value of the setting
|
||||||
|
description (str) : A description of the setting
|
||||||
|
validator (QValidator) : A validator for the setting
|
||||||
|
min_value : The minimum value of the setting
|
||||||
|
max_value : The maximum value of the setting
|
||||||
|
"""
|
||||||
|
|
||||||
DEFAULT_LENGTH = 100
|
DEFAULT_LENGTH = 100
|
||||||
|
|
||||||
|
@ -85,6 +120,7 @@ class FloatSetting(Setting):
|
||||||
min_value: float = None,
|
min_value: float = None,
|
||||||
max_value: float = None,
|
max_value: float = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
"""Create a new float setting."""
|
||||||
super().__init__(name, description, default)
|
super().__init__(name, description, default)
|
||||||
|
|
||||||
# If a validator is given, set it for the QLineEdit widget
|
# If a validator is given, set it for the QLineEdit widget
|
||||||
|
@ -100,6 +136,7 @@ class FloatSetting(Setting):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
|
"""The value of the setting. In this case, a float."""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
|
@ -118,7 +155,16 @@ class FloatSetting(Setting):
|
||||||
|
|
||||||
|
|
||||||
class IntSetting(Setting):
|
class IntSetting(Setting):
|
||||||
"""A setting that is an Integer."""
|
"""A setting that is an Integer.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str) : The name of the setting
|
||||||
|
default : The default value of the setting
|
||||||
|
description (str) : A description of the setting
|
||||||
|
validator (QValidator) : A validator for the setting
|
||||||
|
min_value : The minimum value of the setting
|
||||||
|
max_value : The maximum value of the setting
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
@ -129,6 +175,7 @@ class IntSetting(Setting):
|
||||||
min_value=None,
|
min_value=None,
|
||||||
max_value=None,
|
max_value=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
"""Create a new int setting."""
|
||||||
super().__init__(name, description, default)
|
super().__init__(name, description, default)
|
||||||
|
|
||||||
# If a validator is given, set it for the QLineEdit widget
|
# If a validator is given, set it for the QLineEdit widget
|
||||||
|
@ -146,6 +193,7 @@ class IntSetting(Setting):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
|
"""The value of the setting. In this case, an int."""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
|
@ -166,9 +214,16 @@ class IntSetting(Setting):
|
||||||
|
|
||||||
|
|
||||||
class BooleanSetting(Setting):
|
class BooleanSetting(Setting):
|
||||||
"""A setting that is a Boolean."""
|
"""A setting that is a Boolean.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str) : The name of the setting
|
||||||
|
default : The default value of the setting
|
||||||
|
description (str) : A description of the setting
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, default: bool, description: str) -> None:
|
def __init__(self, name: str, default: bool, description: str) -> None:
|
||||||
|
"""Create a new boolean setting."""
|
||||||
super().__init__(name, description, default)
|
super().__init__(name, description, default)
|
||||||
|
|
||||||
# Overrides the default widget
|
# Overrides the default widget
|
||||||
|
@ -176,6 +231,7 @@ class BooleanSetting(Setting):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
|
"""The value of the setting. In this case, a bool."""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
|
@ -188,6 +244,7 @@ class BooleanSetting(Setting):
|
||||||
|
|
||||||
def get_widget(self):
|
def get_widget(self):
|
||||||
"""Return a widget for the setting.
|
"""Return a widget for the setting.
|
||||||
|
|
||||||
This returns a QCheckBox widget.
|
This returns a QCheckBox widget.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -202,11 +259,19 @@ class BooleanSetting(Setting):
|
||||||
|
|
||||||
|
|
||||||
class SelectionSetting(Setting):
|
class SelectionSetting(Setting):
|
||||||
"""A setting that is a selection from a list of options."""
|
"""A setting that is a selection from a list of options.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str) : The name of the setting
|
||||||
|
options (list) : A list of options to choose from
|
||||||
|
default : The default value of the setting
|
||||||
|
description (str) : A description of the setting
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, name: str, options: list, default: str, description: str
|
self, name: str, options: list, default: str, description: str
|
||||||
) -> None:
|
) -> None:
|
||||||
|
"""Create a new selection setting."""
|
||||||
super().__init__(name, description, default)
|
super().__init__(name, description, default)
|
||||||
# Check if default is in options
|
# Check if default is in options
|
||||||
if default not in options:
|
if default not in options:
|
||||||
|
@ -219,6 +284,7 @@ class SelectionSetting(Setting):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
|
"""The value of the setting. In this case, a string."""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
|
@ -237,6 +303,7 @@ class SelectionSetting(Setting):
|
||||||
|
|
||||||
def get_widget(self):
|
def get_widget(self):
|
||||||
"""Return a widget for the setting.
|
"""Return a widget for the setting.
|
||||||
|
|
||||||
This returns a QComboBox widget.
|
This returns a QComboBox widget.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -252,14 +319,22 @@ class SelectionSetting(Setting):
|
||||||
|
|
||||||
|
|
||||||
class IPSetting(Setting):
|
class IPSetting(Setting):
|
||||||
"""A setting that is an IP address."""
|
"""A setting that is an IP address.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str) : The name of the setting
|
||||||
|
default : The default value of the setting
|
||||||
|
description (str) : A description of the setting
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, default: str, description: str) -> None:
|
def __init__(self, name: str, default: str, description: str) -> None:
|
||||||
|
"""Create a new IP setting."""
|
||||||
super().__init__(name, description)
|
super().__init__(name, description)
|
||||||
self.value = default
|
self.value = default
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
|
"""The value of the setting. In this case, an IP address."""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
|
@ -273,13 +348,21 @@ class IPSetting(Setting):
|
||||||
|
|
||||||
|
|
||||||
class StringSetting(Setting):
|
class StringSetting(Setting):
|
||||||
"""A setting that is a string."""
|
"""A setting that is a string.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str) : The name of the setting
|
||||||
|
default : The default value of the setting
|
||||||
|
description (str) : A description of the setting
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, default: str, description: str) -> None:
|
def __init__(self, name: str, default: str, description: str) -> None:
|
||||||
|
"""Create a new string setting."""
|
||||||
super().__init__(name, description, default)
|
super().__init__(name, description, default)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
|
"""The value of the setting. In this case, a string."""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
"""Module creation for the spectrometer module."""
|
||||||
from nqrduck.module.module import Module
|
from nqrduck.module.module import Module
|
||||||
from .model import SpectrometerModel
|
from .model import SpectrometerModel
|
||||||
from .view import SpectrometerView
|
from .view import SpectrometerView
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
"""View for the Spectrometer Module. Careful - this is not the base class for the spectrometer submodules, but the view for the spectrometer module itself."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from PyQt6.QtWidgets import QWidget, QToolButton, QToolBar, QMenu
|
from PyQt6.QtWidgets import QWidget, QMenu
|
||||||
from PyQt6.QtGui import QAction
|
from PyQt6.QtGui import QAction
|
||||||
from PyQt6.QtCore import pyqtSlot, pyqtSignal
|
from PyQt6.QtCore import pyqtSlot
|
||||||
from nqrduck.module.module_view import ModuleView
|
from nqrduck.module.module_view import ModuleView
|
||||||
from .widget import Ui_Form
|
from .widget import Ui_Form
|
||||||
|
|
||||||
|
@ -9,11 +11,16 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SpectrometerView(ModuleView):
|
class SpectrometerView(ModuleView):
|
||||||
def __init__(self, module):
|
"""The view for the spectrometer module. This class is responsible for displaying the spectrometer module in the main window.
|
||||||
"""This class is the view for the spectrometer module. It contains the menu buttons for the different spectrometers.
|
|
||||||
It also contains the stacked widget that shows the different spectrometer views.
|
It contains the menu buttons for the different spectrometers and the stacked widget that shows the different spectrometer views.
|
||||||
:param module: The spectrometer module that this view belongs to.
|
|
||||||
|
Args:
|
||||||
|
module (Module) : The spectrometer module that this view belongs to
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, module):
|
||||||
|
"""Initializes the spectrometer view. It sets up the UI and the stacked widget for the spectrometers."""
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
|
||||||
widget = QWidget()
|
widget = QWidget()
|
||||||
|
@ -34,8 +41,11 @@ class SpectrometerView(ModuleView):
|
||||||
|
|
||||||
def on_active_spectrometer_changed(self, module):
|
def on_active_spectrometer_changed(self, module):
|
||||||
"""This method is called when the active spectrometer is changed.
|
"""This method is called when the active spectrometer is changed.
|
||||||
|
|
||||||
It changes the active view in the stacked widget to the one that was just activated.
|
It changes the active view in the stacked widget to the one that was just activated.
|
||||||
:param module: The BaseSpectrometer module that was just activated.
|
|
||||||
|
Args:
|
||||||
|
module (BaseSpectrometer) : The spectrometer module that was just activated
|
||||||
"""
|
"""
|
||||||
self._ui_form.stackedWidgetSettings.setCurrentWidget(module.settings_view)
|
self._ui_form.stackedWidgetSettings.setCurrentWidget(module.settings_view)
|
||||||
|
|
||||||
|
@ -52,8 +62,11 @@ class SpectrometerView(ModuleView):
|
||||||
|
|
||||||
def on_spectrometer_widget_changed(self, module):
|
def on_spectrometer_widget_changed(self, module):
|
||||||
"""This method is called when a new spectrometer widget is added to the module.
|
"""This method is called when a new spectrometer widget is added to the module.
|
||||||
|
|
||||||
It adds the widget to the stacked widget and sets it as the current widget.
|
It adds the widget to the stacked widget and sets it as the current widget.
|
||||||
:param widget: The widget that was added to the module.
|
|
||||||
|
Args:
|
||||||
|
module (BaseSpectrometer) : The spectrometer module that was just added
|
||||||
"""
|
"""
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Adding settings widget to stacked widget: %s", module.settings_view
|
"Adding settings widget to stacked widget: %s", module.settings_view
|
||||||
|
@ -72,7 +85,7 @@ class SpectrometerView(ModuleView):
|
||||||
self._ui_form.stackedWidgetPulseProgrammer.setCurrentWidget(
|
self._ui_form.stackedWidgetPulseProgrammer.setCurrentWidget(
|
||||||
module.model.pulse_programmer.pulse_programmer_view
|
module.model.pulse_programmer.pulse_programmer_view
|
||||||
)
|
)
|
||||||
except AttributeError as e:
|
except AttributeError:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"No pulse programmer widget to add for spectrometer %s",
|
"No pulse programmer widget to add for spectrometer %s",
|
||||||
module.model.name,
|
module.model.name,
|
||||||
|
@ -83,7 +96,9 @@ class SpectrometerView(ModuleView):
|
||||||
|
|
||||||
def on_spectrometer_added(self, module):
|
def on_spectrometer_added(self, module):
|
||||||
"""This method changes the active spectrometer to the one that was just added.
|
"""This method changes the active spectrometer to the one that was just added.
|
||||||
:param module: The BaseSpectrometer module that was just added.
|
|
||||||
|
Args:
|
||||||
|
module (BaseSpectrometer) : The spectrometer module that was just added
|
||||||
"""
|
"""
|
||||||
module.change_spectrometer.connect(self.on_menu_button_clicked)
|
module.change_spectrometer.connect(self.on_menu_button_clicked)
|
||||||
self.on_spectrometer_widget_changed(module)
|
self.on_spectrometer_widget_changed(module)
|
||||||
|
@ -119,10 +134,14 @@ class SpectrometerView(ModuleView):
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def on_menu_button_clicked(self, spectrometer_name):
|
def on_menu_button_clicked(self, spectrometer_name):
|
||||||
"""This method is called when a menu button is clicked. It changes the active spectrometer to the one that was clicked.
|
"""This method is called when a menu button is clicked.
|
||||||
|
|
||||||
|
It changes the active spectrometer to the one that was clicked.
|
||||||
It also unchecks all other menu buttons.
|
It also unchecks all other menu buttons.
|
||||||
|
|
||||||
:param spectrometer_name: The name of the spectrometer that was clicked."""
|
Args:
|
||||||
|
spectrometer_name (str) : The name of the spectrometer that was clicked
|
||||||
|
"""
|
||||||
logger.debug("Active module changed to: %s", spectrometer_name)
|
logger.debug("Active module changed to: %s", spectrometer_name)
|
||||||
for action in self._actions.values():
|
for action in self._actions.values():
|
||||||
action.setChecked(False)
|
action.setChecked(False)
|
||||||
|
|
Loading…
Reference in a new issue