This commit is contained in:
jupfi 2024-06-01 21:02:30 +02:00
parent a8c5a93ae5
commit b0cfd270fe
5 changed files with 94 additions and 72 deletions

View file

@ -44,9 +44,6 @@ extend-select = [
"D", # pydocstyle "D", # pydocstyle
] ]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
[tool.ruff.lint.pydocstyle] [tool.ruff.lint.pydocstyle]
convention = "google" convention = "google"

View file

@ -134,7 +134,7 @@ class Function:
""" """
return { return {
"name": self.name, "name": self.name,
"class" : self.__class__.__name__, "class": self.__class__.__name__,
"parameters": [parameter.to_json() for parameter in self.parameters], "parameters": [parameter.to_json() for parameter in self.parameters],
"expression": str(self.expr), "expression": str(self.expr),
"resolution": self.resolution, "resolution": self.resolution,

View file

@ -337,7 +337,8 @@ class T2StarFit(Fit):
def initial_guess(self) -> list: def initial_guess(self) -> list:
"""Initial guess for the T2* fit.""" """Initial guess for the T2* fit."""
return [1, 1] return [1, 1]
class LorentzianFit(Fit): class LorentzianFit(Fit):
"""Lorentzian fit for measurement data.""" """Lorentzian fit for measurement data."""

View file

@ -10,66 +10,70 @@ import logging
from numpy.core.multiarray import array as array from numpy.core.multiarray import array as array
from quackseq.options import BooleanOption, FunctionOption, NumericOption, Option from quackseq.options import BooleanOption, FunctionOption, NumericOption, Option
from quackseq.functions import RectFunction, SincFunction, GaussianFunction, CustomFunction from quackseq.functions import (
RectFunction,
SincFunction,
GaussianFunction,
CustomFunction,
)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
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.
Args:
name (str) : The name of the pulse parameter
Attributes:
name (str) : The name of the pulse parameter
options (OrderedDict) : The options of the pulse parameter
"""
def __init__(self, name: str):
"""Initializes the pulse parameter.
Arguments:
name (str) : The name of the pulse parameter
"""
self.name = name
self.options = list()
def add_option(self, option: Option) -> None:
"""Adds an option to the pulse parameter.
Args: Args:
name (str) : The name of the pulse parameter option (Option) : The option to add
Attributes:
name (str) : The name of the pulse parameter
options (OrderedDict) : The options of the pulse parameter
""" """
self.options.append(option)
def __init__(self, name: str): def get_options(self) -> list:
"""Initializes the pulse parameter. """Gets the options of the pulse parameter.
Arguments: Returns:
name (str) : The name of the pulse parameter list : The options of the pulse parameter
""" """
self.name = name return self.options
self.options = list()
def add_option(self, option: Option) -> None: def get_option_by_name(self, name: str) -> Option:
"""Adds an option to the pulse parameter. """Gets an option by its name.
Args: Args:
option (Option) : The option to add name (str) : The name of the option
"""
self.options.append(option)
def get_options(self) -> list: Returns:
"""Gets the options of the pulse parameter. Option : The option with the specified name
Returns:
list : The options of the pulse parameter
"""
return self.options
def get_option_by_name(self, name: str) -> Option:
"""Gets an option by its name.
Args:
name (str) : The name of the option
Returns:
Option : The option with the specified name
Raises:
ValueError : If no option with the specified name is found
"""
for option in self.options:
if option.name == name:
return option
raise ValueError(f"Option with name {name} not found")
Raises:
ValueError : If no option with the specified name is found
"""
for option in self.options:
if option.name == name:
return option
raise ValueError(f"Option with name {name} not found")
class TXPulse(PulseParameter): class TXPulse(PulseParameter):
@ -104,12 +108,22 @@ class TXPulse(PulseParameter):
self.add_option(NumericOption(self.TX_PHASE, 0)) self.add_option(NumericOption(self.TX_PHASE, 0))
self.add_option( self.add_option(
NumericOption( NumericOption(
self.N_PHASE_CYCLES, 1, is_float=False, min_value=1, max_value=360, slider=False self.N_PHASE_CYCLES,
1,
is_float=False,
min_value=1,
max_value=360,
slider=False,
) )
) )
self.add_option( self.add_option(
NumericOption( NumericOption(
self.PHASE_CYCLE_LEVEL, 0, is_float=False, min_value=0, max_value=10, slider=False self.PHASE_CYCLE_LEVEL,
0,
is_float=False,
min_value=0,
max_value=10,
slider=False,
) )
) )
self.add_option( self.add_option(
@ -124,6 +138,7 @@ class TXPulse(PulseParameter):
), ),
) )
class RXReadout(PulseParameter): class RXReadout(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.
@ -144,6 +159,7 @@ class RXReadout(PulseParameter):
super().__init__(name) super().__init__(name)
self.add_option(BooleanOption(self.RX, False)) self.add_option(BooleanOption(self.RX, False))
class Gate(PulseParameter): class Gate(PulseParameter):
"""Basic PulseParameter for the Gate. It includes an option for the Gate state. """Basic PulseParameter for the Gate. It includes an option for the Gate state.

View file

@ -1,4 +1,5 @@
"""Helper used for signal processing.""" """Helper used for signal processing."""
import logging import logging
from scipy.fft import fft, fftfreq, fftshift from scipy.fft import fft, fftfreq, fftshift
import numpy as np import numpy as np
@ -6,25 +7,28 @@ import sympy
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class SignalProcessing: class SignalProcessing:
"""This class provides various signal processing methods that can then be used by nqrduck modules.""" """This class provides various signal processing methods that can then be used by nqrduck modules."""
@classmethod @classmethod
def fft(cls, tdx : np.array, tdy: np.array, freq_shift : float = 0, zero_padding = 1000) -> tuple[np.array, np.array]: def fft(
cls, tdx: np.array, tdy: np.array, freq_shift: float = 0, zero_padding=1000
) -> tuple[np.array, np.array]:
"""This method calculates the FFT of the time domain data. """This method calculates the FFT of the time domain data.
Args: Args:
tdx (np.array): Time domain x data in seconds. tdx (np.array): Time domain x data in seconds.
tdy (np.array): Time domain magnitude y data. tdy (np.array): Time domain magnitude y data.
freq_shift (float): Frequency shift in MHz - this can be useful if the spectrometer has it's frequency data in the IF band. freq_shift (float): Frequency shift in MHz - this can be useful if the spectrometer has it's frequency data in the IF band.
zero_padding (float): Zero padding to be used in the FFT. zero_padding (float): Zero padding to be used in the FFT.
Returns: Returns:
np.array: Frequency domain x data in MHz. np.array: Frequency domain x data in MHz.
np.array: Frequency domain magnitude y data. np.array: Frequency domain magnitude y data.
""" """
dwell_time = (tdx[1] - tdx[0]) dwell_time = tdx[1] - tdx[0]
N = len(tdx) + zero_padding N = len(tdx) + zero_padding
if freq_shift != 0: if freq_shift != 0:
@ -33,53 +37,57 @@ class SignalProcessing:
# Apply the shift by multiplying the time domain signal # Apply the shift by multiplying the time domain signal
tdy_shift = np.abs(tdy * shift_signal) tdy_shift = np.abs(tdy * shift_signal)
ydf = fftshift(fft(tdy_shift, N, axis=0), axes=0) ydf = fftshift(fft(tdy_shift, N, axis=0), axes=0)
else: else:
ydf = fftshift(fft(tdy, N, axis=0), axes=0) ydf = fftshift(fft(tdy, N, axis=0), axes=0)
xdf = fftshift(fftfreq(N, dwell_time)) xdf = fftshift(fftfreq(N, dwell_time))
return xdf, ydf return xdf, ydf
@classmethod @classmethod
def baseline_correction(cls, fdx : np.array, fdy : np.array, order : int) -> np.array: def baseline_correction(cls, fdx: np.array, fdy: np.array, order: int) -> np.array:
"""This method calculates the baseline correction of the frequency domain data. """This method calculates the baseline correction of the frequency domain data.
Args: Args:
fdx (np.array): Frequency domain x data in MHz. fdx (np.array): Frequency domain x data in MHz.
fdy (np.array): Frequency domain magnitude y data. fdy (np.array): Frequency domain magnitude y data.
order (int): Order of the polynomial used for baseline correction. order (int): Order of the polynomial used for baseline correction.
Returns: Returns:
np.array: Frequency domain magnitude y data with baseline correction. np.array: Frequency domain magnitude y data with baseline correction.
""" """
pass pass
@classmethod @classmethod
def apodization(cls, tdx : np.array, tdy : np.array, apodization_function : sympy.Expr) -> np.array: def apodization(
cls, tdx: np.array, tdy: np.array, apodization_function: sympy.Expr
) -> np.array:
"""This method calculates the apodization of the time domain data. """This method calculates the apodization of the time domain data.
Args: Args:
tdx (np.array): Time domain x data in seconds. tdx (np.array): Time domain x data in seconds.
tdy (np.array): Time domain magnitude y data. tdy (np.array): Time domain magnitude y data.
apodization_function (sympy.Expr): Apodization function. apodization_function (sympy.Expr): Apodization function.
Returns: Returns:
np.array: Time domain magnitude y data with apodization. np.array: Time domain magnitude y data with apodization.
""" """
weight = np.array([apodization_function.subs("t", t) for t in tdx]) weight = np.array([apodization_function.subs("t", t) for t in tdx])
return tdy * weight return tdy * weight
@classmethod @classmethod
def peak_picking(cls, fdx: np.array, fdy: np.array, threshold : float = 0.05) -> tuple[np.array, np.array]: def peak_picking(
cls, fdx: np.array, fdy: np.array, threshold: float = 0.05
) -> tuple[np.array, np.array]:
"""This method calculates the peak picking of the frequency domain data. """This method calculates the peak picking of the frequency domain data.
Args: Args:
fdx (np.array): Frequency domain x data in MHz. fdx (np.array): Frequency domain x data in MHz.
fdy (np.array): Frequency domain magnitude y data. fdy (np.array): Frequency domain magnitude y data.
threshold (float): Threshold for peak picking. threshold (float): Threshold for peak picking.
Returns: Returns:
list: x,y data of the peaks. list: x,y data of the peaks.
""" """