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
]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
[tool.ruff.lint.pydocstyle]
convention = "google"

View file

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

View file

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

View file

@ -10,66 +10,70 @@ import logging
from numpy.core.multiarray import array as array
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__)
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:
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
option (Option) : The option to add
"""
self.options.append(option)
def __init__(self, name: str):
"""Initializes the pulse parameter.
def get_options(self) -> list:
"""Gets the options of the pulse parameter.
Arguments:
name (str) : The name of the pulse parameter
"""
self.name = name
self.options = list()
Returns:
list : The options of the pulse parameter
"""
return self.options
def add_option(self, option: Option) -> None:
"""Adds an option to the pulse parameter.
def get_option_by_name(self, name: str) -> Option:
"""Gets an option by its name.
Args:
option (Option) : The option to add
"""
self.options.append(option)
Args:
name (str) : The name of the option
def get_options(self) -> list:
"""Gets the options of the pulse parameter.
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")
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")
class TXPulse(PulseParameter):
@ -104,12 +108,22 @@ class TXPulse(PulseParameter):
self.add_option(NumericOption(self.TX_PHASE, 0))
self.add_option(
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(
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(
@ -124,6 +138,7 @@ class TXPulse(PulseParameter):
),
)
class RXReadout(PulseParameter):
"""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)
self.add_option(BooleanOption(self.RX, False))
class Gate(PulseParameter):
"""Basic PulseParameter for the Gate. It includes an option for the Gate state.

View file

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