mirror of
https://github.com/nqrduck/nqrduck-spectrometer.git
synced 2024-11-09 20:40:02 +00:00
Added docstrings.
This commit is contained in:
parent
8371149a43
commit
3882be0054
2 changed files with 143 additions and 41 deletions
|
@ -11,12 +11,10 @@ class SpectrometerController(ModuleController):
|
||||||
"""This class is the controller for the spectrometer module."""
|
"""This class is the controller for the spectrometer module."""
|
||||||
|
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
"""This method initializes the controller.
|
"""This method initializes the controller."""
|
||||||
:param module: The module that this controller belongs to.
|
|
||||||
"""
|
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
|
||||||
def _load_spectrometer_modules(self):
|
def _load_spectrometer_modules(self) -> None:
|
||||||
"""This method loads the spectrometer (sub-)modules and adds them to the spectrometer model."""
|
"""This method loads the spectrometer (sub-)modules and adds them to the spectrometer model."""
|
||||||
# Get the modules with entry points in the nqrduck group
|
# Get the modules with entry points in the nqrduck group
|
||||||
modules = MainController._get_modules()
|
modules = MainController._get_modules()
|
||||||
|
@ -40,7 +38,15 @@ class SpectrometerController(ModuleController):
|
||||||
|
|
||||||
self._module.view.create_menu_entry()
|
self._module.view.create_menu_entry()
|
||||||
|
|
||||||
def process_signals(self, key: str, value: None):
|
def process_signals(self, key: str, value: object) -> None:
|
||||||
|
"""This method processes the signals from the nqrduck module.
|
||||||
|
It is called by the nqrduck module when a signal is emitted.
|
||||||
|
It then calls the corresponding method of the spectrometer model.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): Name of the signal.
|
||||||
|
value (object): Value of the signal.
|
||||||
|
"""
|
||||||
# This signal starts a measurement
|
# This signal starts a measurement
|
||||||
if key == "start_measurement":
|
if key == "start_measurement":
|
||||||
self.on_measurement_start()
|
self.on_measurement_start()
|
||||||
|
@ -51,7 +57,7 @@ class SpectrometerController(ModuleController):
|
||||||
elif key == "set_averages":
|
elif key == "set_averages":
|
||||||
self.module.model.active_spectrometer.controller.set_averages(value)
|
self.module.model.active_spectrometer.controller.set_averages(value)
|
||||||
|
|
||||||
def on_loading(self):
|
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.
|
||||||
"""
|
"""
|
||||||
|
@ -63,7 +69,7 @@ class SpectrometerController(ModuleController):
|
||||||
)
|
)
|
||||||
self._load_spectrometer_modules()
|
self._load_spectrometer_modules()
|
||||||
|
|
||||||
def on_measurement_start(self):
|
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.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -28,14 +28,28 @@ class Function:
|
||||||
self.end_x = 1
|
self.end_x = 1
|
||||||
|
|
||||||
def get_time_points(self, pulse_length: Decimal) -> np.ndarray:
|
def get_time_points(self, pulse_length: Decimal) -> np.ndarray:
|
||||||
"""Returns the time domain points for the function with the given pulse length."""
|
"""Returns the time domain points for the function with the given pulse length.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pulse_length (Decimal): The pulse length in seconds.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
np.ndarray: The time domain points.
|
||||||
|
"""
|
||||||
# Get the time domain points
|
# Get the time domain points
|
||||||
n = int(pulse_length / self.resolution)
|
n = int(pulse_length / self.resolution)
|
||||||
t = np.linspace(0, float(pulse_length), n)
|
t = np.linspace(0, float(pulse_length), n)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def evaluate(self, pulse_length: Decimal) -> np.ndarray:
|
def evaluate(self, pulse_length: Decimal) -> np.ndarray:
|
||||||
"""Evaluates the function for the given pulse length."""
|
"""Evaluates the function for the given pulse length.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pulse_length (Decimal): The pulse length in seconds.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
np.ndarray: The evaluated function.
|
||||||
|
"""
|
||||||
n = int(pulse_length / self.resolution)
|
n = int(pulse_length / self.resolution)
|
||||||
t = np.linspace(self.start_x, self.end_x, n)
|
t = np.linspace(self.start_x, self.end_x, n)
|
||||||
x = sympy.symbols("x")
|
x = sympy.symbols("x")
|
||||||
|
@ -54,12 +68,28 @@ class Function:
|
||||||
|
|
||||||
return f(t)
|
return f(t)
|
||||||
|
|
||||||
def get_tdx(self, pulse_length : float) -> None:
|
def get_tdx(self, pulse_length: float) -> np.ndarray:
|
||||||
|
"""Returns the time domain points and the evaluated function for the given pulse length.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pulse_length (float): The pulse length in seconds.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
np.ndarray: The time domain points.
|
||||||
|
"""
|
||||||
n = int(pulse_length / self.resolution)
|
n = int(pulse_length / self.resolution)
|
||||||
t = np.linspace(self.start_x, self.end_x, n)
|
t = np.linspace(self.start_x, self.end_x, n)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def frequency_domain_plot(self, pulse_length: Decimal) -> MplWidget:
|
def frequency_domain_plot(self, pulse_length: Decimal) -> MplWidget:
|
||||||
|
"""Plots the frequency domain of the function for the given pulse length.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pulse_length (Decimal): The pulse length in seconds.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
MplWidget: The matplotlib widget containing the plot.
|
||||||
|
"""
|
||||||
mpl_widget = MplWidget()
|
mpl_widget = MplWidget()
|
||||||
td = self.get_time_points(pulse_length)
|
td = self.get_time_points(pulse_length)
|
||||||
yd = self.evaluate(pulse_length)
|
yd = self.evaluate(pulse_length)
|
||||||
|
@ -71,6 +101,14 @@ class Function:
|
||||||
return mpl_widget
|
return mpl_widget
|
||||||
|
|
||||||
def time_domain_plot(self, pulse_length: Decimal) -> MplWidget:
|
def time_domain_plot(self, pulse_length: Decimal) -> MplWidget:
|
||||||
|
"""Plots the time domain of the function for the given pulse length.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pulse_length (Decimal): The pulse length in seconds.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
MplWidget: The matplotlib widget containing the plot.
|
||||||
|
"""
|
||||||
mpl_widget = MplWidget()
|
mpl_widget = MplWidget()
|
||||||
td = self.get_time_points(pulse_length)
|
td = self.get_time_points(pulse_length)
|
||||||
mpl_widget.canvas.ax.plot(td, abs(self.evaluate(pulse_length)))
|
mpl_widget.canvas.ax.plot(td, abs(self.evaluate(pulse_length)))
|
||||||
|
@ -80,13 +118,29 @@ class Function:
|
||||||
return mpl_widget
|
return mpl_widget
|
||||||
|
|
||||||
def get_pulse_amplitude(self, pulse_length: Decimal) -> np.array:
|
def get_pulse_amplitude(self, pulse_length: Decimal) -> np.array:
|
||||||
"""Returns the pulse amplitude in the time domain."""
|
"""Returns the pulse amplitude in the time domain.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pulse_length (Decimal): The pulse length in seconds.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
np.array: The pulse amplitude.
|
||||||
|
"""
|
||||||
return self.evaluate(pulse_length)
|
return self.evaluate(pulse_length)
|
||||||
|
|
||||||
def add_parameter(self, parameter: "Function.Parameter"):
|
def add_parameter(self, parameter: "Function.Parameter") -> None:
|
||||||
|
"""Adds a parameter to the function.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
parameter (Function.Parameter): The parameter to add."""
|
||||||
self.parameters.append(parameter)
|
self.parameters.append(parameter)
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self) -> dict:
|
||||||
|
"""Returns a json representation of the function.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: The json representation of the function.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"parameters": [parameter.to_json() for parameter in self.parameters],
|
"parameters": [parameter.to_json() for parameter in self.parameters],
|
||||||
|
@ -97,7 +151,15 @@ class Function:
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, data):
|
def from_json(cls, data: dict) -> "Function":
|
||||||
|
"""Creates a function from a json representation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (dict): The json representation of the function.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Function: The function.
|
||||||
|
"""
|
||||||
for subclass in cls.__subclasses__():
|
for subclass in cls.__subclasses__():
|
||||||
if subclass.name == data["name"]:
|
if subclass.name == data["name"]:
|
||||||
cls = subclass
|
cls = subclass
|
||||||
|
@ -118,6 +180,7 @@ class Function:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def expr(self):
|
def expr(self):
|
||||||
|
"""The sympy expression of the function."""
|
||||||
return self._expr
|
return self._expr
|
||||||
|
|
||||||
@expr.setter
|
@expr.setter
|
||||||
|
@ -178,7 +241,6 @@ class Function:
|
||||||
pixmap = PulseParamters.TXCustom()
|
pixmap = PulseParamters.TXCustom()
|
||||||
return pixmap
|
return pixmap
|
||||||
|
|
||||||
|
|
||||||
class Parameter:
|
class Parameter:
|
||||||
def __init__(self, name: str, symbol: str, value: float) -> None:
|
def __init__(self, name: str, symbol: str, value: float) -> None:
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -186,11 +248,21 @@ class Function:
|
||||||
self.value = value
|
self.value = value
|
||||||
self.default = value
|
self.default = value
|
||||||
|
|
||||||
def set_value(self, value: float):
|
def set_value(self, value: float) -> None:
|
||||||
|
"""Sets the value of the parameter.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value (float): The new value of the parameter.
|
||||||
|
"""
|
||||||
self.value = value
|
self.value = value
|
||||||
logger.debug("Parameter %s set to %s", self.name, self.value)
|
logger.debug("Parameter %s set to %s", self.name, self.value)
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self) -> dict:
|
||||||
|
"""Returns a json representation of the parameter.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: The json representation of the parameter.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"symbol": self.symbol,
|
"symbol": self.symbol,
|
||||||
|
@ -200,11 +272,22 @@ class Function:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, data):
|
def from_json(cls, data):
|
||||||
|
"""Creates a parameter from a json representation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (dict): The json representation of the parameter.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Function.Parameter: The parameter.
|
||||||
|
"""
|
||||||
obj = cls(data["name"], data["symbol"], data["value"])
|
obj = cls(data["name"], data["symbol"], data["value"])
|
||||||
obj.default = data["default"]
|
obj.default = data["default"]
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
class RectFunction(Function):
|
class RectFunction(Function):
|
||||||
|
"""The rectangular function."""
|
||||||
|
|
||||||
name = "Rectangular"
|
name = "Rectangular"
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
@ -217,6 +300,8 @@ class RectFunction(Function):
|
||||||
|
|
||||||
|
|
||||||
class SincFunction(Function):
|
class SincFunction(Function):
|
||||||
|
"""The sinc function."""
|
||||||
|
|
||||||
name = "Sinc"
|
name = "Sinc"
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
@ -232,6 +317,8 @@ class SincFunction(Function):
|
||||||
|
|
||||||
|
|
||||||
class GaussianFunction(Function):
|
class GaussianFunction(Function):
|
||||||
|
"""The Gaussian function."""
|
||||||
|
|
||||||
name = "Gaussian"
|
name = "Gaussian"
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
@ -254,12 +341,15 @@ class GaussianFunction(Function):
|
||||||
|
|
||||||
|
|
||||||
class CustomFunction(Function):
|
class CustomFunction(Function):
|
||||||
|
"""A custom function."""
|
||||||
|
|
||||||
name = "Custom"
|
name = "Custom"
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
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."""
|
||||||
|
|
||||||
|
@ -288,8 +378,10 @@ class Option:
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
class BooleanOption(Option):
|
class BooleanOption(Option):
|
||||||
"""Defines a boolean option for a pulse parameter option."""
|
"""Defines a boolean option for a pulse parameter option."""
|
||||||
|
|
||||||
TYPE = "Boolean"
|
TYPE = "Boolean"
|
||||||
|
|
||||||
def set_value(self, value):
|
def set_value(self, value):
|
||||||
|
@ -298,6 +390,7 @@ class BooleanOption(Option):
|
||||||
|
|
||||||
class NumericOption(Option):
|
class NumericOption(Option):
|
||||||
"""Defines a numeric option for a pulse parameter option."""
|
"""Defines a numeric option for a pulse parameter option."""
|
||||||
|
|
||||||
TYPE = "Numeric"
|
TYPE = "Numeric"
|
||||||
|
|
||||||
def set_value(self, value):
|
def set_value(self, value):
|
||||||
|
@ -307,6 +400,7 @@ class NumericOption(Option):
|
||||||
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."""
|
||||||
|
|
||||||
TYPE = "Function"
|
TYPE = "Function"
|
||||||
|
|
||||||
def __init__(self, name, functions) -> None:
|
def __init__(self, name, functions) -> None:
|
||||||
|
@ -346,11 +440,13 @@ class TXPulse(BaseSpectrometerModel.PulseParameter):
|
||||||
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))
|
||||||
self.add_option(
|
self.add_option(
|
||||||
FunctionOption(self.TX_PULSE_SHAPE, [RectFunction(), SincFunction(), GaussianFunction(), CustomFunction()]),
|
FunctionOption(
|
||||||
|
self.TX_PULSE_SHAPE,
|
||||||
|
[RectFunction(), SincFunction(), GaussianFunction(), CustomFunction()],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_pixmap(self):
|
def get_pixmap(self):
|
||||||
|
|
||||||
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:
|
||||||
|
@ -360,12 +456,12 @@ class TXPulse(BaseSpectrometerModel.PulseParameter):
|
||||||
|
|
||||||
class RXReadout(BaseSpectrometerModel.PulseParameter):
|
class RXReadout(BaseSpectrometerModel.PulseParameter):
|
||||||
RX = "RX"
|
RX = "RX"
|
||||||
|
|
||||||
def __init__(self, name) -> None:
|
def __init__(self, name) -> None:
|
||||||
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:
|
if self.get_option_by_name(self.RX).value == False:
|
||||||
pixmap = PulseParamters.RXOff()
|
pixmap = PulseParamters.RXOff()
|
||||||
else:
|
else:
|
||||||
|
@ -375,12 +471,12 @@ class RXReadout(BaseSpectrometerModel.PulseParameter):
|
||||||
|
|
||||||
class Gate(BaseSpectrometerModel.PulseParameter):
|
class Gate(BaseSpectrometerModel.PulseParameter):
|
||||||
GATE_STATE = "Gate State"
|
GATE_STATE = "Gate State"
|
||||||
|
|
||||||
def __init__(self, name) -> None:
|
def __init__(self, name) -> None:
|
||||||
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:
|
if self.get_option_by_name(self.GATE_STATE).value == False:
|
||||||
pixmap = PulseParamters.GateOff()
|
pixmap = PulseParamters.GateOff()
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue