From 0ec31e541d99a334435e7179296c8727502acb96 Mon Sep 17 00:00:00 2001 From: jupfi Date: Wed, 29 May 2024 10:03:19 +0200 Subject: [PATCH] Improved setting structure. --- .../spectrometer/spectrometer_model.py | 70 +++++++++++++++---- .../spectrometer/spectrometer_settings.py | 41 +++++++---- 2 files changed, 82 insertions(+), 29 deletions(-) diff --git a/src/quackseq/spectrometer/spectrometer_model.py b/src/quackseq/spectrometer/spectrometer_model.py index eeff852..bd7def0 100644 --- a/src/quackseq/spectrometer/spectrometer_model.py +++ b/src/quackseq/spectrometer/spectrometer_model.py @@ -2,10 +2,36 @@ import logging from collections import OrderedDict +from typing import Any from quackseq.spectrometer.spectrometer_settings import Setting logger = logging.getLogger(__name__) +class QuackSettings(OrderedDict): + def __getattr__(self, key): + return self[key].value + + def __setattr__(self, key, value): + self[key].value = value + + @property + def categories(self): + categories = [] + + for setting in self.values(): + if not setting.category in categories: + categories.append(setting.category) + + return categories + + def get_settings_by_category(self, category): + settings = [] + + for setting in self.values(): + if setting.category == category: + settings.append(setting) + + return settings class SpectrometerModel(): """The base class for all spectrometer models. @@ -13,31 +39,30 @@ class SpectrometerModel(): It contains the settings and pulse parameters of the spectrometer. Attributes: - settings (OrderedDict) : The settings of the spectrometer + settings (QuackSettings) : The settings of the spectrometer """ - settings: OrderedDict + settings: QuackSettings def __init__(self): """Initializes the spectrometer model.""" - self.settings = OrderedDict() + self.settings = QuackSettings() - def add_setting(self, setting: Setting, category: str) -> None: + + def add_setting(self,name: str, setting: Setting) -> None: """Adds a setting to the spectrometer. Args: + name (str) : The name of the setting as it should be used in the code setting (Setting) : The setting to add - category (str) : The category of the setting """ - if category not in self.settings.keys(): - self.settings[category] = [] - self.settings[category].append(setting) + self.settings[name] = setting def get_setting_by_name(self, name: str) -> Setting: """Gets a setting by its name. Args: - name (str) : The name of the setting + name (str) : The name of the setting as it is used in the code Returns: Setting : The setting with the specified name @@ -45,12 +70,29 @@ class SpectrometerModel(): Raises: ValueError : If no setting with the specified name is found """ - for category in self.settings.keys(): - for setting in self.settings[category]: - if setting.name == name: - return setting - raise ValueError(f"Setting with name {name} not found") + if name in self.settings: + return self.settings[name] + + raise ValueError(f"No setting with name {name} found") + + def get_setting_by_display_name(self, display_name : str) -> Setting: + """Gets a setting by its display name. + Args: + display_name (str) : The display name of the setting + + Returns: + Setting : The setting with the specified display name + + Raises: + ValueError : If no setting with the specified display name is found + """ + for setting in self.settings.values(): + if setting.name == display_name: + return setting + + raise ValueError(f"No setting with display name {display_name} found") + @property def target_frequency(self): """The target frequency of the spectrometer in Hz. This is the frequency where the magnetic resonance experiment is performed.""" diff --git a/src/quackseq/spectrometer/spectrometer_settings.py b/src/quackseq/spectrometer/spectrometer_settings.py index 5bd7b8e..858e0b4 100644 --- a/src/quackseq/spectrometer/spectrometer_settings.py +++ b/src/quackseq/spectrometer/spectrometer_settings.py @@ -11,7 +11,8 @@ class Setting(): E.g. the Transmit gain or the number of points in a spectrum. Args: - name (str) : The name of the setting + name (str) : The name of the setting as it is used in the code + category (str) : The category of the setting description (str) : A description of the setting default : The default value of the setting @@ -19,9 +20,10 @@ class Setting(): name (str) : The name of the setting description (str) : A description of the setting value : The value of the setting + category (str) : The category of the setting """ - def __init__(self, name: str, description: str = None, default=None) -> None: + def __init__(self, name: str, category : str, description: str = None, default=None) -> None: """Create a new setting. Args: @@ -29,9 +31,9 @@ class Setting(): description (str): A description of the setting. default: The default value of the setting. """ - self.widget = None super().__init__() self.name = name + self.category = category self.description = description if default is not None: self.value = default @@ -46,11 +48,12 @@ class NumericalSetting(Setting): """ def __init__( - self, name: str, description: str, default, min_value=None, max_value=None + self, name: str, category: str, description: str, default, min_value=None, max_value=None ) -> None: """Create a new numerical setting.""" super().__init__( name, + category, self.description_limit_info(description, min_value, max_value), default, ) @@ -81,6 +84,7 @@ class FloatSetting(NumericalSetting): Args: name (str) : The name of the setting + category (str) : The category of the setting default : The default value of the setting description (str) : A description of the setting min_value : The minimum value of the setting @@ -92,14 +96,14 @@ class FloatSetting(NumericalSetting): def __init__( self, name: str, + category: str, default: float, description: str, min_value: float = None, max_value: float = None, ) -> None: """Create a new float setting.""" - super().__init__(name, description, default, min_value, max_value) - + super().__init__(name, category, description, default, min_value, max_value) @property def value(self): """The value of the setting. In this case, a float.""" @@ -107,7 +111,7 @@ class FloatSetting(NumericalSetting): @value.setter def value(self, value): - logger.debug(f"Setting {self.name} to {value}") + logger.debug(f"Setting {self.name} to {value}") self._value = float(value) @@ -116,6 +120,7 @@ class IntSetting(NumericalSetting): Args: name (str) : The name of the setting + category (str) : The category of the setting default : The default value of the setting description (str) : A description of the setting min_value : The minimum value of the setting @@ -125,13 +130,15 @@ class IntSetting(NumericalSetting): def __init__( self, name: str, + category: str, default: int, description: str, min_value=None, max_value=None, ) -> None: """Create a new int setting.""" - super().__init__(name, description, default, min_value, max_value) + super().__init__(name, category, description, default, min_value, max_value) + @property def value(self): @@ -142,6 +149,7 @@ class IntSetting(NumericalSetting): def value(self, value): logger.debug(f"Setting {self.name} to {value}") value = int(float(value)) + self._value = value @@ -150,13 +158,14 @@ class BooleanSetting(Setting): Args: name (str) : The name of the setting + category (str) : The category 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, category : str, default: bool, description: str) -> None: """Create a new boolean setting.""" - super().__init__(name, description, default) + super().__init__(name, category, description, default) @property @@ -178,16 +187,17 @@ class SelectionSetting(Setting): Args: name (str) : The name of the setting + category (str) : The category 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__( - self, name: str, options: list, default: str, description: str + self, name: str, category : str, options: list, default: str, description: str ) -> None: """Create a new selection setting.""" - super().__init__(name, description, default) + super().__init__(name, category, description, default) # Check if default is in options if default not in options: raise ValueError("Default value must be one of the options") @@ -206,7 +216,7 @@ class SelectionSetting(Setting): if value in self.options: self._value = value else: - raise ValueError("Value must be one of the options") + raise ValueError(f"Value must be one of the options {self.options}") # This fixes a bug when creating the widget when the options are not yet set except AttributeError: self._value = value @@ -219,13 +229,14 @@ class StringSetting(Setting): Args: name (str) : The name of the setting + category (str) : The category 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, category :str, default: str, description: str) -> None: """Create a new string setting.""" - super().__init__(name, description, default) + super().__init__(name, category, description, default) @property def value(self):