mirror of
https://github.com/nqrduck/nqrduck-spectrometer-limenqr.git
synced 2024-11-09 11:10:03 +00:00
Linting.
This commit is contained in:
parent
f926398596
commit
2c63fa4028
5 changed files with 409 additions and 178 deletions
|
@ -0,0 +1 @@
|
||||||
|
"""Init file for the nqrduck_spectrometer_limenqr package."""
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""Controller module for the Lime NQR spectrometer."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -10,24 +12,33 @@ from nqrduck_spectrometer.base_spectrometer_controller import BaseSpectrometerCo
|
||||||
from nqrduck_spectrometer.measurement import Measurement
|
from nqrduck_spectrometer.measurement import Measurement
|
||||||
from nqrduck_spectrometer.pulseparameters import TXPulse, RXReadout
|
from nqrduck_spectrometer.pulseparameters import TXPulse, RXReadout
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class LimeNQRController(BaseSpectrometerController):
|
class LimeNQRController(BaseSpectrometerController):
|
||||||
|
"""Controller class for the Lime NQR spectrometer."""
|
||||||
|
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
|
"""Initializes the LimeNQRController."""
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
|
||||||
def start_measurement(self):
|
def start_measurement(self):
|
||||||
|
"""Starts the measurement procedure."""
|
||||||
self.log_start_message()
|
self.log_start_message()
|
||||||
|
|
||||||
lime = self.initialize_lime()
|
lime = self.initialize_lime()
|
||||||
if lime is None:
|
if lime is None:
|
||||||
# Emit error message
|
# Emit error message
|
||||||
self.emit_measurement_error("Error with Lime driver. Is the Lime driver installed?")
|
self.emit_measurement_error(
|
||||||
|
"Error with Lime driver. Is the Lime driver installed?"
|
||||||
|
)
|
||||||
return -1
|
return -1
|
||||||
elif lime.Npulses == 0:
|
elif lime.Npulses == 0:
|
||||||
# Emit error message
|
# Emit error message
|
||||||
self.emit_measurement_error("Error with pulse sequence. Is the pulse sequence empty?")
|
self.emit_measurement_error(
|
||||||
|
"Error with pulse sequence. Is the pulse sequence empty?"
|
||||||
|
)
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
self.setup_lime_parameters(lime)
|
self.setup_lime_parameters(lime)
|
||||||
|
@ -37,7 +48,9 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
|
|
||||||
if not self.perform_measurement(lime):
|
if not self.perform_measurement(lime):
|
||||||
self.emit_status_message("Measurement failed")
|
self.emit_status_message("Measurement failed")
|
||||||
self.emit_measurement_error("Error with measurement data. Did you set an RX event?")
|
self.emit_measurement_error(
|
||||||
|
"Error with measurement data. Did you set an RX event?"
|
||||||
|
)
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
measurement_data = self.process_measurement_results(lime)
|
measurement_data = self.process_measurement_results(lime)
|
||||||
|
@ -48,12 +61,14 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
else:
|
else:
|
||||||
self.emit_measurement_error("Measurement failed. Unable to retrieve data.")
|
self.emit_measurement_error("Measurement failed. Unable to retrieve data.")
|
||||||
|
|
||||||
def log_start_message(self):
|
def log_start_message(self) -> None:
|
||||||
"""This method logs a message when the measurement is started."""
|
"""Logs a message when the measurement is started."""
|
||||||
logger.debug("Starting measurement with spectrometer: %s", self.module.model.name)
|
logger.debug(
|
||||||
|
"Starting measurement with spectrometer: %s", self.module.model.name
|
||||||
|
)
|
||||||
|
|
||||||
def initialize_lime(self):
|
def initialize_lime(self) -> PyLimeConfig:
|
||||||
"""This method initializes the limr object that is used to communicate with the pulseN driver.
|
"""Initializes the limr object that is used to communicate with the pulseN driver.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
PyLimeConfig: The PyLimeConfig object that is used to communicate with the pulseN driver
|
PyLimeConfig: The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
|
@ -67,17 +82,18 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Error while initializing Lime driver: %s", e)
|
logger.error("Error while initializing Lime driver: %s", e)
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def setup_lime_parameters(self, lime):
|
def setup_lime_parameters(self, lime: PyLimeConfig) -> None:
|
||||||
"""This method sets the parameters of the lime config according to the settings set in the spectrometer module.
|
"""Sets the parameters of the lime config according to the settings set in the spectrometer module.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
"""
|
"""
|
||||||
#lime.noi = -1
|
# lime.noi = -1
|
||||||
lime.override_init = -1
|
lime.override_init = -1
|
||||||
#
|
#
|
||||||
# lime.nrp = 1
|
# lime.nrp = 1
|
||||||
|
@ -87,19 +103,19 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
lime.averages = self.module.model.averages
|
lime.averages = self.module.model.averages
|
||||||
self.log_lime_parameters(lime)
|
self.log_lime_parameters(lime)
|
||||||
|
|
||||||
def setup_temporary_storage(self, lime):
|
def setup_temporary_storage(self, lime: PyLimeConfig) -> None:
|
||||||
"""This method sets up the temporary storage for the measurement data.
|
"""Sets up the temporary storage for the measurement data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
"""
|
"""
|
||||||
temp_dir = tempfile.TemporaryDirectory()
|
temp_dir = tempfile.TemporaryDirectory()
|
||||||
logger.debug("Created temporary directory at: %s", temp_dir.name)
|
logger.debug("Created temporary directory at: %s", temp_dir.name)
|
||||||
lime.save_path = str(Path(temp_dir.name)) + "/" # Temporary storage path
|
lime.save_path = str(Path(temp_dir.name)) + "/" # Temporary storage path
|
||||||
lime.file_pattern = "temp" # Temporary filename prefix or related config
|
lime.file_pattern = "temp" # Temporary filename prefix or related config
|
||||||
|
|
||||||
def perform_measurement(self, lime):
|
def perform_measurement(self, lime: PyLimeConfig) -> bool:
|
||||||
"""This method executes the measurement procedure.
|
"""Executes the measurement procedure.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
|
@ -115,8 +131,8 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
logger.error("Failed to execute the measurement: %s", e)
|
logger.error("Failed to execute the measurement: %s", e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def process_measurement_results(self, lime):
|
def process_measurement_results(self, lime: PyLimeConfig) -> Measurement:
|
||||||
"""This method processes the measurement results and returns a Measurement object.
|
"""Processes the measurement results and returns a Measurement object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
|
@ -133,8 +149,10 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
logger.debug("RX event begins at: %sµs and ends at: %sµs", rx_begin, rx_stop)
|
logger.debug("RX event begins at: %sµs and ends at: %sµs", rx_begin, rx_stop)
|
||||||
return self.calculate_measurement_data(lime, rx_begin, rx_stop)
|
return self.calculate_measurement_data(lime, rx_begin, rx_stop)
|
||||||
|
|
||||||
def calculate_measurement_data(self, lime, rx_begin, rx_stop):
|
def calculate_measurement_data(
|
||||||
"""This method calculates the measurement data from the limr object.
|
self, lime: PyLimeConfig, rx_begin: float, rx_stop: float
|
||||||
|
) -> Measurement:
|
||||||
|
"""Calculates the measurement data from the limr object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
|
@ -146,34 +164,44 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
path = lime.get_path()
|
path = lime.get_path()
|
||||||
hdf = HDF(path)
|
hdf = HDF(path)
|
||||||
evidx = self.find_evaluation_range_indices(hdf, rx_begin, rx_stop)
|
evidx = self.find_evaluation_range_indices(hdf, rx_begin, rx_stop)
|
||||||
tdx, tdy = self.extract_measurement_data(lime, hdf, evidx)
|
tdx, tdy = self.extract_measurement_data(lime, hdf, evidx)
|
||||||
fft_shift = self.get_fft_shift()
|
fft_shift = self.get_fft_shift()
|
||||||
return Measurement(tdx, tdy, self.module.model.target_frequency, frequency_shift=fft_shift, IF_frequency=self.module.model.if_frequency)
|
return Measurement(
|
||||||
|
tdx,
|
||||||
|
tdy,
|
||||||
|
self.module.model.target_frequency,
|
||||||
|
frequency_shift=fft_shift,
|
||||||
|
IF_frequency=self.module.model.if_frequency,
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Error processing measurement result: %s", e)
|
logger.error("Error processing measurement result: %s", e)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def find_evaluation_range_indices(self, hdf, rx_begin, rx_stop):
|
def find_evaluation_range_indices(
|
||||||
"""This method finds the indices of the evaluation range in the measurement data.
|
self, hdf: HDF, rx_begin: float, rx_stop: float
|
||||||
|
) -> list:
|
||||||
|
"""Finds the indices of the evaluation range in the measurement data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
HDF (HDF): The HDF object that is used to read the measurement data
|
hdf (HDF): The HDF object that is used to read the measurement data
|
||||||
rx_begin (float): The start time of the RX event in µs
|
rx_begin (float): The start time of the RX event in µs
|
||||||
rx_stop (float): The stop time of the RX event in µs
|
rx_stop (float): The stop time of the RX event in µs
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: The indices of the evaluation range in the measurement data
|
list: The indices of the evaluation range in the measurement data
|
||||||
"""
|
"""
|
||||||
return np.where((hdf.tdx > rx_begin) & (hdf.tdx < rx_stop))[0]
|
return np.where((hdf.tdx > rx_begin) & (hdf.tdx < rx_stop))[0]
|
||||||
|
|
||||||
def extract_measurement_data(self, lime, hdf, indices):
|
def extract_measurement_data(
|
||||||
"""This method extracts the measurement data from the limr object.
|
self, lime: PyLimeConfig, hdf: HDF, indices: list
|
||||||
|
) -> tuple:
|
||||||
|
"""Extracts the measurement data from the PyLimeConfig object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
HDF (HDF): The HDF object that is used to read the measurement data
|
hdf (HDF): The HDF object that is used to read the measurement data
|
||||||
indices (list): The indices of the evaluation range in the measurement data
|
indices (list): The indices of the evaluation range in the measurement data
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -185,17 +213,19 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
tdy = tdy.flatten()
|
tdy = tdy.flatten()
|
||||||
return tdx, tdy
|
return tdx, tdy
|
||||||
|
|
||||||
def get_fft_shift(self):
|
def get_fft_shift(self) -> int:
|
||||||
"""This method returns the FFT shift value from the settings.
|
"""Rreturns the FFT shift value from the settings.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
int: The FFT shift value
|
int: The FFT shift value
|
||||||
"""
|
"""
|
||||||
fft_shift_enabled = self.module.model.get_setting_by_name(self.module.model.FFT_SHIFT).value
|
fft_shift_enabled = self.module.model.get_setting_by_name(
|
||||||
|
self.module.model.FFT_SHIFT
|
||||||
|
).value
|
||||||
return self.module.model.if_frequency if fft_shift_enabled else 0
|
return self.module.model.if_frequency if fft_shift_enabled else 0
|
||||||
|
|
||||||
def emit_measurement_data(self, measurement_data):
|
def emit_measurement_data(self, measurement_data: Measurement) -> None:
|
||||||
"""This method emits the measurement data to the GUI.
|
"""Emits the measurement data to the GUI.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
measurement_data (Measurement): The measurement data
|
measurement_data (Measurement): The measurement data
|
||||||
|
@ -203,16 +233,16 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
logger.debug("Emitting measurement data")
|
logger.debug("Emitting measurement data")
|
||||||
self.module.nqrduck_signal.emit("measurement_data", measurement_data)
|
self.module.nqrduck_signal.emit("measurement_data", measurement_data)
|
||||||
|
|
||||||
def emit_status_message(self, message):
|
def emit_status_message(self, message: str) -> None:
|
||||||
"""This method emits a status message to the GUI.
|
"""Emits a status message to the GUI.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message (str): The status message
|
message (str): The status message
|
||||||
"""
|
"""
|
||||||
self.module.nqrduck_signal.emit("statusbar_message", message)
|
self.module.nqrduck_signal.emit("statusbar_message", message)
|
||||||
|
|
||||||
def emit_measurement_error(self, error_message):
|
def emit_measurement_error(self, error_message: str) -> None:
|
||||||
"""This method emits a measurement error to the GUI.
|
"""Emits a measurement error to the GUI.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
error_message (str): The error message
|
error_message (str): The error message
|
||||||
|
@ -220,24 +250,24 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
logger.error(error_message)
|
logger.error(error_message)
|
||||||
self.module.nqrduck_signal.emit("measurement_error", error_message)
|
self.module.nqrduck_signal.emit("measurement_error", error_message)
|
||||||
|
|
||||||
def log_lime_parameters(self, lime):
|
def log_lime_parameters(self, lime: PyLimeConfig) -> None:
|
||||||
"""This method logs the parameters of the limr object.
|
"""Logs the parameters of the limr object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
"""
|
"""
|
||||||
# for key, value in lime.__dict__.items():
|
# for key, value in lime.__dict__.items():
|
||||||
# logger.debug("Lime parameter %s has value %s", key, value)
|
# logger.debug("Lime parameter %s has value %s", key, value)
|
||||||
logger.debug("Lime parameter %s has value %s", "srate", lime.srate)
|
logger.debug("Lime parameter %s has value %s", "srate", lime.srate)
|
||||||
|
|
||||||
def update_settings(self, lime):
|
def update_settings(self, lime: PyLimeConfig) -> PyLimeConfig:
|
||||||
"""This method sets the parameters of the limr object according to the settings set in the spectrometer module.
|
"""Sets the parameters of the limr object according to the settings set in the spectrometer module.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
lime: The updated limr object
|
lime: The updated limr object
|
||||||
"""
|
"""
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Updating settings for spectrometer: %s for measurement",
|
"Updating settings for spectrometer: %s for measurement",
|
||||||
|
@ -259,7 +289,9 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
lime.RX_matching = setting.get_setting()
|
lime.RX_matching = setting.get_setting()
|
||||||
# Careful this doesn't only set the IF frequency but the local oscillator frequency
|
# Careful this doesn't only set the IF frequency but the local oscillator frequency
|
||||||
elif setting.name == self.module.model.IF_FREQUENCY:
|
elif setting.name == self.module.model.IF_FREQUENCY:
|
||||||
lime.frq = self.module.model.target_frequency - setting.get_setting()
|
lime.frq = (
|
||||||
|
self.module.model.target_frequency - setting.get_setting()
|
||||||
|
)
|
||||||
self.module.model.if_frequency = setting.get_setting()
|
self.module.model.if_frequency = setting.get_setting()
|
||||||
elif setting.name == self.module.model.ACQUISITION_TIME:
|
elif setting.name == self.module.model.ACQUISITION_TIME:
|
||||||
lime.rectime_secs = setting.get_setting()
|
lime.rectime_secs = setting.get_setting()
|
||||||
|
@ -309,8 +341,8 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
lime.c3_tim = c3_tim
|
lime.c3_tim = c3_tim
|
||||||
return lime
|
return lime
|
||||||
|
|
||||||
def translate_pulse_sequence(self, lime):
|
def translate_pulse_sequence(self, lime: PyLimeConfig) -> PyLimeConfig:
|
||||||
"""This method translates the pulse sequence to the limr object.
|
"""Ttranslates the pulse sequence to the limr object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
|
@ -325,15 +357,25 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
self.log_parameter_details(parameter)
|
self.log_parameter_details(parameter)
|
||||||
|
|
||||||
if self.is_translatable_tx_parameter(parameter):
|
if self.is_translatable_tx_parameter(parameter):
|
||||||
pulse_shape, pulse_amplitude = self.prepare_pulse_amplitude(event, parameter)
|
pulse_shape, pulse_amplitude = self.prepare_pulse_amplitude(
|
||||||
pulse_amplitude, modulated_phase = self.modulate_pulse_amplitude(pulse_amplitude, event, lime)
|
event, parameter
|
||||||
|
)
|
||||||
|
pulse_amplitude, modulated_phase = self.modulate_pulse_amplitude(
|
||||||
|
pulse_amplitude, event, lime
|
||||||
|
)
|
||||||
|
|
||||||
if first_pulse: # If the pulse frequency list is empty
|
if first_pulse: # If the pulse frequency list is empty
|
||||||
pfr, pdr, pam, pof, pph = self.initialize_pulse_lists(lime, pulse_amplitude, pulse_shape, modulated_phase)
|
pfr, pdr, pam, pof, pph = self.initialize_pulse_lists(
|
||||||
|
lime, pulse_amplitude, pulse_shape, modulated_phase
|
||||||
|
)
|
||||||
first_pulse = False
|
first_pulse = False
|
||||||
else:
|
else:
|
||||||
pfr_ext, pdr_ext, pam_ext, pph_ext = self.extend_pulse_lists(lime, pulse_amplitude, pulse_shape, modulated_phase)
|
pfr_ext, pdr_ext, pam_ext, pph_ext = self.extend_pulse_lists(
|
||||||
pof_ext = self.calculate_and_set_offsets(lime, pulse_shape, events, event, pulse_amplitude)
|
pulse_amplitude, pulse_shape, modulated_phase
|
||||||
|
)
|
||||||
|
pof_ext = self.calculate_and_set_offsets(
|
||||||
|
lime, pulse_shape, events, event, pulse_amplitude
|
||||||
|
)
|
||||||
|
|
||||||
pfr.extend(pfr_ext)
|
pfr.extend(pfr_ext)
|
||||||
pdr.extend(pdr_ext)
|
pdr.extend(pdr_ext)
|
||||||
|
@ -351,8 +393,9 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
lime.Npulses = len(lime.p_frq)
|
lime.Npulses = len(lime.p_frq)
|
||||||
return lime
|
return lime
|
||||||
|
|
||||||
def get_number_of_pulses(self):
|
def get_number_of_pulses(self) -> int:
|
||||||
"""This method calculates the number of pulses in the pulse sequence before the LimeDriverBinding is initialized.
|
"""Calculates the number of pulses in the pulse sequence before the LimeDriverBinding is initialized.
|
||||||
|
|
||||||
This makes sure it"s initialized with the correct size of the pulse lists.
|
This makes sure it"s initialized with the correct size of the pulse lists.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -371,31 +414,35 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
|
|
||||||
# Helper functions below:
|
# Helper functions below:
|
||||||
|
|
||||||
def fetch_pulse_sequence_events(self):
|
def fetch_pulse_sequence_events(self) -> list:
|
||||||
"""This method fetches the pulse sequence events from the pulse programmer module.
|
"""Fetches the pulse sequence events from the pulse programmer module.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: The pulse sequence events
|
list: The pulse sequence events
|
||||||
"""
|
"""
|
||||||
return self.module.model.pulse_programmer.model.pulse_sequence.events
|
return self.module.model.pulse_programmer.model.pulse_sequence.events
|
||||||
|
|
||||||
def log_event_details(self, event):
|
def log_event_details(self, event) -> None:
|
||||||
|
"""Logs the details of an event."""
|
||||||
logger.debug("Event %s has parameters: %s", event.name, event.parameters)
|
logger.debug("Event %s has parameters: %s", event.name, event.parameters)
|
||||||
|
|
||||||
def log_parameter_details(self, parameter):
|
def log_parameter_details(self, parameter) -> None:
|
||||||
|
"""Logs the details of a parameter."""
|
||||||
logger.debug("Parameter %s has options: %s", parameter.name, parameter.options)
|
logger.debug("Parameter %s has options: %s", parameter.name, parameter.options)
|
||||||
|
|
||||||
def is_translatable_tx_parameter(self, parameter):
|
def is_translatable_tx_parameter(self, parameter):
|
||||||
"""This method checks if a parameter a pulse with a transmit pulse shape (amplitude nonzero)
|
"""Checks if a parameter a pulse with a transmit pulse shape (amplitude nonzero).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
parameter (Parameter): The parameter to check
|
parameter (Parameter): The parameter to check
|
||||||
"""
|
"""
|
||||||
return (parameter.name == self.module.model.TX and
|
return (
|
||||||
parameter.get_option_by_name(TXPulse.RELATIVE_AMPLITUDE).value > 0)
|
parameter.name == self.module.model.TX
|
||||||
|
and parameter.get_option_by_name(TXPulse.RELATIVE_AMPLITUDE).value > 0
|
||||||
|
)
|
||||||
|
|
||||||
def prepare_pulse_amplitude(self, event, parameter):
|
def prepare_pulse_amplitude(self, event, parameter):
|
||||||
"""This method prepares the pulse amplitude for the limr object.
|
"""Prepares the pulse amplitude for the limr object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
event (Event): The event that contains the parameter
|
event (Event): The event that contains the parameter
|
||||||
|
@ -405,13 +452,16 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
tuple: A tuple containing the pulse shape and the pulse amplitude
|
tuple: A tuple containing the pulse shape and the pulse amplitude
|
||||||
"""
|
"""
|
||||||
pulse_shape = parameter.get_option_by_name(TXPulse.TX_PULSE_SHAPE).value
|
pulse_shape = parameter.get_option_by_name(TXPulse.TX_PULSE_SHAPE).value
|
||||||
pulse_amplitude = abs(pulse_shape.get_pulse_amplitude(event.duration)) * \
|
pulse_amplitude = abs(pulse_shape.get_pulse_amplitude(event.duration)) * (
|
||||||
(parameter.get_option_by_name(TXPulse.RELATIVE_AMPLITUDE).value / 100)
|
parameter.get_option_by_name(TXPulse.RELATIVE_AMPLITUDE).value / 100
|
||||||
|
)
|
||||||
pulse_amplitude = np.clip(pulse_amplitude, -0.99, 0.99)
|
pulse_amplitude = np.clip(pulse_amplitude, -0.99, 0.99)
|
||||||
return pulse_shape, pulse_amplitude
|
return pulse_shape, pulse_amplitude
|
||||||
|
|
||||||
def modulate_pulse_amplitude(self, pulse_amplitude, event, lime):
|
def modulate_pulse_amplitude(
|
||||||
"""This method modulates the pulse amplitude for the limr object. We need to do this to have the pulse at IF frequency instead of LO frequency.
|
self, pulse_amplitude: float, event, lime: PyLimeConfig
|
||||||
|
) -> tuple:
|
||||||
|
"""Modulates the pulse amplitude for the limr object. We need to do this to have the pulse at IF frequency instead of LO frequency.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
pulse_amplitude (float): The pulse amplitude
|
pulse_amplitude (float): The pulse amplitude
|
||||||
|
@ -430,58 +480,72 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
modulated_phase = self.unwrap_phase(np.angle(pulse_complex))
|
modulated_phase = self.unwrap_phase(np.angle(pulse_complex))
|
||||||
return modulated_amplitude, modulated_phase
|
return modulated_amplitude, modulated_phase
|
||||||
|
|
||||||
def unwrap_phase(self, phase):
|
def unwrap_phase(self, phase: float) -> float:
|
||||||
"""This method unwraps the phase of the pulse.
|
"""This method unwraps the phase of the pulse.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
phase (float): The phase of the pulse
|
phase (float): The phase of the pulse
|
||||||
"""
|
"""
|
||||||
return (np.unwrap(phase) + 2 * np.pi) % (2 * np.pi)
|
return (np.unwrap(phase) + 2 * np.pi) % (2 * np.pi)
|
||||||
|
|
||||||
def initialize_pulse_lists(self, lime, pulse_amplitude, pulse_shape, modulated_phase):
|
def initialize_pulse_lists(
|
||||||
|
self,
|
||||||
|
lime: PyLimeConfig,
|
||||||
|
pulse_amplitude: np.array,
|
||||||
|
pulse_shape,
|
||||||
|
modulated_phase: np.array,
|
||||||
|
) -> tuple:
|
||||||
"""This method initializes the pulse lists of the limr object.
|
"""This method initializes the pulse lists of the limr object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
pulse_amplitude (float): The pulse amplitude
|
pulse_amplitude (np.array): The pulse amplitude
|
||||||
pulse_shape (PulseShape): The pulse shape
|
pulse_shape (Function): The pulse shape
|
||||||
modulated_phase (float): The modulated phase
|
modulated_phase (np.array): The modulated phase
|
||||||
"""
|
"""
|
||||||
pfr = [float(self.module.model.if_frequency)] * len(pulse_amplitude)
|
pfr = [float(self.module.model.if_frequency)] * len(pulse_amplitude)
|
||||||
# We set the first len(pulse_amplitude) of the p_dur
|
# We set the first len(pulse_amplitude) of the p_dur
|
||||||
pdr = [float(pulse_shape.resolution)] * len(pulse_amplitude)
|
pdr = [float(pulse_shape.resolution)] * len(pulse_amplitude)
|
||||||
pam = list(pulse_amplitude)
|
pam = list(pulse_amplitude)
|
||||||
pof = ([self.module.model.OFFSET_FIRST_PULSE] +
|
pof = [self.module.model.OFFSET_FIRST_PULSE] + [
|
||||||
[int(pulse_shape.resolution * lime.srate)] * (len(pulse_amplitude) - 1))
|
int(pulse_shape.resolution * lime.srate)
|
||||||
|
] * (len(pulse_amplitude) - 1)
|
||||||
pph = list(modulated_phase)
|
pph = list(modulated_phase)
|
||||||
|
|
||||||
return pfr, pdr, pam, pof, pph
|
return pfr, pdr, pam, pof, pph
|
||||||
|
|
||||||
def extend_pulse_lists(self, lime, pulse_amplitude, pulse_shape, modulated_phase):
|
def extend_pulse_lists(self, pulse_amplitude, pulse_shape, modulated_phase):
|
||||||
"""This method extends the pulse lists of the limr object.
|
"""This method extends the pulse lists of the limr object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
|
||||||
pulse_amplitude (float): The pulse amplitude
|
pulse_amplitude (float): The pulse amplitude
|
||||||
pulse_shape (PulseShape): The pulse shape
|
pulse_shape (PulseShape): The pulse shape
|
||||||
modulated_phase (float): The modulated phase
|
modulated_phase (float): The modulated phase
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: A tuple containing the extended pulse lists (frequency, duration, amplitude, phase)
|
||||||
"""
|
"""
|
||||||
pfr = ([float(self.module.model.if_frequency)] * len(pulse_amplitude))
|
pfr = [float(self.module.model.if_frequency)] * len(pulse_amplitude)
|
||||||
pdr = ([float(pulse_shape.resolution)] * len(pulse_amplitude))
|
pdr = [float(pulse_shape.resolution)] * len(pulse_amplitude)
|
||||||
pam = (list(pulse_amplitude))
|
pam = list(pulse_amplitude)
|
||||||
pph = (list(modulated_phase))
|
pph = list(modulated_phase)
|
||||||
|
|
||||||
return pfr, pdr, pam, pph
|
return pfr, pdr, pam, pph
|
||||||
|
|
||||||
def calculate_and_set_offsets(self, lime, pulse_shape, events, current_event, pulse_amplitude):
|
def calculate_and_set_offsets(
|
||||||
|
self, lime: PyLimeConfig, pulse_shape, events, current_event, pulse_amplitude
|
||||||
|
) -> list:
|
||||||
"""This method calculates and sets the offsets for the limr object.
|
"""This method calculates and sets the offsets for the limr object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
lime (PyLimeConfig): The PyLimeConfig object that is used to communicate with the pulseN driver
|
||||||
pulse_shape (PulseShape): The pulse shape
|
pulse_shape (Function): The pulse shape
|
||||||
events (list): The pulse sequence events
|
events (list): The pulse sequence events
|
||||||
current_event (Event): The current event
|
current_event (Event): The current event
|
||||||
pulse_amplitude (float): The pulse amplitude
|
pulse_amplitude (float): The pulse amplitude
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: The offsets for the limr object
|
||||||
"""
|
"""
|
||||||
blank_durations = self.get_blank_durations_before_event(events, current_event)
|
blank_durations = self.get_blank_durations_before_event(events, current_event)
|
||||||
|
|
||||||
|
@ -500,7 +564,8 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
pof.extend([offset_per_sample] * (len(pulse_amplitude) - 1))
|
pof.extend([offset_per_sample] * (len(pulse_amplitude) - 1))
|
||||||
return pof
|
return pof
|
||||||
|
|
||||||
def get_blank_durations_before_event(self, events, current_event):
|
# This method could be refactored in a potential pulse sequence module
|
||||||
|
def get_blank_durations_before_event(self, events, current_event) -> list:
|
||||||
"""This method returns the blank durations before the current event.
|
"""This method returns the blank durations before the current event.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -511,12 +576,15 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
list: The blank durations before the current event
|
list: The blank durations before the current event
|
||||||
"""
|
"""
|
||||||
blank_durations = []
|
blank_durations = []
|
||||||
previous_events_without_tx_pulse = self.get_previous_events_without_tx_pulse(events, current_event)
|
previous_events_without_tx_pulse = self.get_previous_events_without_tx_pulse(
|
||||||
|
events, current_event
|
||||||
|
)
|
||||||
for event in previous_events_without_tx_pulse:
|
for event in previous_events_without_tx_pulse:
|
||||||
blank_durations.append(float(event.duration))
|
blank_durations.append(float(event.duration))
|
||||||
return blank_durations
|
return blank_durations
|
||||||
|
|
||||||
def get_previous_events_without_tx_pulse(self, events, current_event):
|
# This method could be refactored in a potential pulse sequence module
|
||||||
|
def get_previous_events_without_tx_pulse(self, events, current_event) -> list:
|
||||||
"""This method returns the previous events without a transmit pulse.
|
"""This method returns the previous events without a transmit pulse.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -530,15 +598,19 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
previous_events = events[:index]
|
previous_events = events[:index]
|
||||||
result = []
|
result = []
|
||||||
for event in reversed(previous_events):
|
for event in reversed(previous_events):
|
||||||
translatable = any(self.is_translatable_tx_parameter(param) for param in event.parameters.values())
|
translatable = any(
|
||||||
|
self.is_translatable_tx_parameter(param)
|
||||||
|
for param in event.parameters.values()
|
||||||
|
)
|
||||||
if not translatable:
|
if not translatable:
|
||||||
result.append(event)
|
result.append(event)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
return reversed(result) # Reversed to maintain the original order if needed elsewhere
|
return reversed(
|
||||||
|
result
|
||||||
|
) # Reversed to maintain the original order if needed elsewhere
|
||||||
|
|
||||||
|
def translate_rx_event(self, lime : PyLimeConfig) -> tuple:
|
||||||
def translate_rx_event(self, lime):
|
|
||||||
"""This method translates the RX event of the pulse sequence to the limr object.
|
"""This method translates the RX event of the pulse sequence to the limr object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -547,19 +619,25 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
Returns:
|
Returns:
|
||||||
tuple: A tuple containing the start and stop time of the RX event in µs
|
tuple: A tuple containing the start and stop time of the RX event in µs
|
||||||
"""
|
"""
|
||||||
CORRECTION_FACTOR = self.module.model.get_setting_by_name(self.module.model.RX_OFFSET).value
|
CORRECTION_FACTOR = self.module.model.get_setting_by_name(
|
||||||
|
self.module.model.RX_OFFSET
|
||||||
|
).value
|
||||||
events = self.module.model.pulse_programmer.model.pulse_sequence.events
|
events = self.module.model.pulse_programmer.model.pulse_sequence.events
|
||||||
|
|
||||||
rx_event = self.find_rx_event(events)
|
rx_event = self.find_rx_event(events)
|
||||||
if not rx_event:
|
if not rx_event:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
previous_events_duration = self.calculate_previous_events_duration(events, rx_event)
|
previous_events_duration = self.calculate_previous_events_duration(
|
||||||
|
events, rx_event
|
||||||
|
)
|
||||||
rx_duration = float(rx_event.duration)
|
rx_duration = float(rx_event.duration)
|
||||||
|
|
||||||
offset = self.calculate_offset(lime)
|
offset = self.calculate_offset(lime)
|
||||||
|
|
||||||
rx_begin = float(previous_events_duration) + float(offset) + float(CORRECTION_FACTOR)
|
rx_begin = (
|
||||||
|
float(previous_events_duration) + float(offset) + float(CORRECTION_FACTOR)
|
||||||
|
)
|
||||||
rx_stop = rx_begin + rx_duration
|
rx_stop = rx_begin + rx_duration
|
||||||
return rx_begin * 1e6, rx_stop * 1e6
|
return rx_begin * 1e6, rx_stop * 1e6
|
||||||
|
|
||||||
|
@ -593,7 +671,7 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
previous_events = events[: events.index(rx_event)]
|
previous_events = events[: events.index(rx_event)]
|
||||||
return sum(event.duration for event in previous_events)
|
return sum(event.duration for event in previous_events)
|
||||||
|
|
||||||
def calculate_offset(self, lime):
|
def calculate_offset(self, lime :PyLimeConfig) -> float:
|
||||||
"""This method calculates the offset for the RX event.
|
"""This method calculates the offset for the RX event.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -604,8 +682,7 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
"""
|
"""
|
||||||
return self.module.model.OFFSET_FIRST_PULSE * (1 / lime.srate)
|
return self.module.model.OFFSET_FIRST_PULSE * (1 / lime.srate)
|
||||||
|
|
||||||
|
def set_frequency(self, value: float) -> None:
|
||||||
def set_frequency(self, value: float):
|
|
||||||
"""This method sets the target frequency of the spectrometer.
|
"""This method sets the target frequency of the spectrometer.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -622,7 +699,7 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
)
|
)
|
||||||
self.module.nqrduck_signal.emit("failure_set_frequency", value)
|
self.module.nqrduck_signal.emit("failure_set_frequency", value)
|
||||||
|
|
||||||
def set_averages(self, value: int):
|
def set_averages(self, value: int) -> None:
|
||||||
"""This method sets the number of averages for the spectrometer.
|
"""This method sets the number of averages for the spectrometer.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""BaseSpectrometer for Lime NQR spectrometer."""
|
||||||
|
|
||||||
from nqrduck_spectrometer.base_spectrometer import BaseSpectrometer
|
from nqrduck_spectrometer.base_spectrometer import BaseSpectrometer
|
||||||
from .model import LimeNQRModel
|
from .model import LimeNQRModel
|
||||||
from .view import LimeNQRView
|
from .view import LimeNQRView
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
"""Model for the Lime NQR spectrometer."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from nqrduck_spectrometer.base_spectrometer_model import BaseSpectrometerModel
|
from nqrduck_spectrometer.base_spectrometer_model import BaseSpectrometerModel
|
||||||
from nqrduck_spectrometer.pulseparameters import TXPulse, RXReadout
|
from nqrduck_spectrometer.pulseparameters import TXPulse, RXReadout
|
||||||
from nqrduck_spectrometer.settings import FloatSetting, IntSetting, BooleanSetting, SelectionSetting
|
from nqrduck_spectrometer.settings import (
|
||||||
|
FloatSetting,
|
||||||
|
IntSetting,
|
||||||
|
BooleanSetting,
|
||||||
|
SelectionSetting,
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class LimeNQRModel(BaseSpectrometerModel):
|
class LimeNQRModel(BaseSpectrometerModel):
|
||||||
|
"""Model for the Lime NQR spectrometer."""
|
||||||
# Setting constants for the names of the spectrometer settings
|
# Setting constants for the names of the spectrometer settings
|
||||||
CHANNEL = "TX/RX Channel"
|
CHANNEL = "TX/RX Channel"
|
||||||
TX_MATCHING = "TX Matching"
|
TX_MATCHING = "TX Matching"
|
||||||
|
@ -49,91 +57,228 @@ class LimeNQRModel(BaseSpectrometerModel):
|
||||||
# Settings that are not changed by the user
|
# Settings that are not changed by the user
|
||||||
OFFSET_FIRST_PULSE = 300
|
OFFSET_FIRST_PULSE = 300
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, module) -> None:
|
def __init__(self, module) -> None:
|
||||||
|
"""Initializes the Lime NQR model."""
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
# Acquisition settings
|
# Acquisition settings
|
||||||
channel_options = ["0", "1"]
|
channel_options = ["0", "1"]
|
||||||
channel_setting = SelectionSetting(self.CHANNEL, channel_options, "0", "TX/RX Channel")
|
channel_setting = SelectionSetting(
|
||||||
|
self.CHANNEL, channel_options, "0", "TX/RX Channel"
|
||||||
|
)
|
||||||
self.add_setting(channel_setting, self.ACQUISITION)
|
self.add_setting(channel_setting, self.ACQUISITION)
|
||||||
|
|
||||||
tx_matching_options = ["0", "1"]
|
tx_matching_options = ["0", "1"]
|
||||||
tx_matching_setting = SelectionSetting(self.TX_MATCHING, tx_matching_options, "0", "TX Matching")
|
tx_matching_setting = SelectionSetting(
|
||||||
|
self.TX_MATCHING, tx_matching_options, "0", "TX Matching"
|
||||||
|
)
|
||||||
self.add_setting(tx_matching_setting, self.ACQUISITION)
|
self.add_setting(tx_matching_setting, self.ACQUISITION)
|
||||||
|
|
||||||
rx_matching_options = ["0", "1"]
|
rx_matching_options = ["0", "1"]
|
||||||
rx_matching_setting = SelectionSetting(self.RX_MATCHING, rx_matching_options, "0", "RX Matching")
|
rx_matching_setting = SelectionSetting(
|
||||||
|
self.RX_MATCHING, rx_matching_options, "0", "RX Matching"
|
||||||
|
)
|
||||||
self.add_setting(rx_matching_setting, self.ACQUISITION)
|
self.add_setting(rx_matching_setting, self.ACQUISITION)
|
||||||
|
|
||||||
sampling_frequency_setting = FloatSetting(self.SAMPLING_FREQUENCY, 30.72e6, "The rate at which the spectrometer samples the input signal.", min_value=0, max_value=30.72e6)
|
sampling_frequency_setting = FloatSetting(
|
||||||
|
self.SAMPLING_FREQUENCY,
|
||||||
|
30.72e6,
|
||||||
|
"The rate at which the spectrometer samples the input signal.",
|
||||||
|
min_value=0,
|
||||||
|
max_value=30.72e6,
|
||||||
|
)
|
||||||
self.add_setting(sampling_frequency_setting, self.ACQUISITION)
|
self.add_setting(sampling_frequency_setting, self.ACQUISITION)
|
||||||
|
|
||||||
if_frequency_setting = FloatSetting(self.IF_FREQUENCY, 5e6, "The intermediate frequency to which the input signal is down converted during analog-to-digital conversion.", min_value=0)
|
if_frequency_setting = FloatSetting(
|
||||||
|
self.IF_FREQUENCY,
|
||||||
|
5e6,
|
||||||
|
"The intermediate frequency to which the input signal is down converted during analog-to-digital conversion.",
|
||||||
|
min_value=0,
|
||||||
|
)
|
||||||
self.add_setting(if_frequency_setting, self.ACQUISITION)
|
self.add_setting(if_frequency_setting, self.ACQUISITION)
|
||||||
self.if_frequency = 5e6
|
self.if_frequency = 5e6
|
||||||
|
|
||||||
acquisition_time_setting = FloatSetting(self.ACQUISITION_TIME, 82e-6, "Acquisition time - this is from the beginning of the pulse sequence", min_value=0)
|
acquisition_time_setting = FloatSetting(
|
||||||
|
self.ACQUISITION_TIME,
|
||||||
|
82e-6,
|
||||||
|
"Acquisition time - this is from the beginning of the pulse sequence",
|
||||||
|
min_value=0,
|
||||||
|
)
|
||||||
self.add_setting(acquisition_time_setting, self.ACQUISITION)
|
self.add_setting(acquisition_time_setting, self.ACQUISITION)
|
||||||
|
|
||||||
# Gate Settings
|
# Gate Settings
|
||||||
gate_enable_setting = BooleanSetting(self.GATE_ENABLE, True, "Setting that controls whether gate is on during transmitting.")
|
gate_enable_setting = BooleanSetting(
|
||||||
|
self.GATE_ENABLE,
|
||||||
|
True,
|
||||||
|
"Setting that controls whether gate is on during transmitting.",
|
||||||
|
)
|
||||||
self.add_setting(gate_enable_setting, self.GATE_SETTINGS)
|
self.add_setting(gate_enable_setting, self.GATE_SETTINGS)
|
||||||
|
|
||||||
gate_padding_left_setting = IntSetting(self.GATE_PADDING_LEFT, 10, "The number of samples by which to extend the gate window to the left.", min_value=0)
|
gate_padding_left_setting = IntSetting(
|
||||||
|
self.GATE_PADDING_LEFT,
|
||||||
|
10,
|
||||||
|
"The number of samples by which to extend the gate window to the left.",
|
||||||
|
min_value=0,
|
||||||
|
)
|
||||||
self.add_setting(gate_padding_left_setting, self.GATE_SETTINGS)
|
self.add_setting(gate_padding_left_setting, self.GATE_SETTINGS)
|
||||||
|
|
||||||
gate_padding_right_setting = IntSetting(self.GATE_PADDING_RIGHT, 10, "The number of samples by which to extend the gate window to the right.", min_value=0)
|
gate_padding_right_setting = IntSetting(
|
||||||
|
self.GATE_PADDING_RIGHT,
|
||||||
|
10,
|
||||||
|
"The number of samples by which to extend the gate window to the right.",
|
||||||
|
min_value=0,
|
||||||
|
)
|
||||||
self.add_setting(gate_padding_right_setting, self.GATE_SETTINGS)
|
self.add_setting(gate_padding_right_setting, self.GATE_SETTINGS)
|
||||||
|
|
||||||
gate_shift_setting = IntSetting(self.GATE_SHIFT, 53, "The delay, in number of samples, by which the gate window is shifted.", min_value=0)
|
gate_shift_setting = IntSetting(
|
||||||
|
self.GATE_SHIFT,
|
||||||
|
53,
|
||||||
|
"The delay, in number of samples, by which the gate window is shifted.",
|
||||||
|
min_value=0,
|
||||||
|
)
|
||||||
self.add_setting(gate_shift_setting, self.GATE_SETTINGS)
|
self.add_setting(gate_shift_setting, self.GATE_SETTINGS)
|
||||||
|
|
||||||
# RX/TX settings
|
# RX/TX settings
|
||||||
rx_gain_setting = IntSetting(self.RX_GAIN, 55, "The gain level of the receiver’s amplifier.", min_value=0, max_value=55, spin_box=(True, True))
|
rx_gain_setting = IntSetting(
|
||||||
|
self.RX_GAIN,
|
||||||
|
55,
|
||||||
|
"The gain level of the receiver’s amplifier.",
|
||||||
|
min_value=0,
|
||||||
|
max_value=55,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(rx_gain_setting, self.RX_TX_SETTINGS)
|
self.add_setting(rx_gain_setting, self.RX_TX_SETTINGS)
|
||||||
|
|
||||||
tx_gain_setting = IntSetting(self.TX_GAIN, 30, "The gain level of the transmitter’s amplifier.", min_value=0, max_value=55, spin_box=(True, True))
|
tx_gain_setting = IntSetting(
|
||||||
|
self.TX_GAIN,
|
||||||
|
30,
|
||||||
|
"The gain level of the transmitter’s amplifier.",
|
||||||
|
min_value=0,
|
||||||
|
max_value=55,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(tx_gain_setting, self.RX_TX_SETTINGS)
|
self.add_setting(tx_gain_setting, self.RX_TX_SETTINGS)
|
||||||
|
|
||||||
rx_lpf_bw_setting = FloatSetting(self.RX_LPF_BW, 30.72e6/2, "The bandwidth of the receiver’s low-pass filter which attenuates frequencies below a certain threshold.")
|
rx_lpf_bw_setting = FloatSetting(
|
||||||
|
self.RX_LPF_BW,
|
||||||
|
30.72e6 / 2,
|
||||||
|
"The bandwidth of the receiver’s low-pass filter which attenuates frequencies below a certain threshold.",
|
||||||
|
)
|
||||||
self.add_setting(rx_lpf_bw_setting, self.RX_TX_SETTINGS)
|
self.add_setting(rx_lpf_bw_setting, self.RX_TX_SETTINGS)
|
||||||
|
|
||||||
tx_lpf_bw_setting = FloatSetting(self.TX_LPF_BW, 130.0e6, "The bandwidth of the transmitter’s low-pass filter which limits the frequency range of the transmitted signa")
|
tx_lpf_bw_setting = FloatSetting(
|
||||||
|
self.TX_LPF_BW,
|
||||||
|
130.0e6,
|
||||||
|
"The bandwidth of the transmitter’s low-pass filter which limits the frequency range of the transmitted signa",
|
||||||
|
)
|
||||||
self.add_setting(tx_lpf_bw_setting, self.RX_TX_SETTINGS)
|
self.add_setting(tx_lpf_bw_setting, self.RX_TX_SETTINGS)
|
||||||
|
|
||||||
# Calibration settings
|
# Calibration settings
|
||||||
tx_i_dc_correction_setting = IntSetting(self.TX_I_DC_CORRECTION, -45, "Adjusts the direct current offset errors in the in-phase (I) component of the transmit (TX) path.", min_value=-128, max_value=127, spin_box=(True, True))
|
tx_i_dc_correction_setting = IntSetting(
|
||||||
|
self.TX_I_DC_CORRECTION,
|
||||||
|
-45,
|
||||||
|
"Adjusts the direct current offset errors in the in-phase (I) component of the transmit (TX) path.",
|
||||||
|
min_value=-128,
|
||||||
|
max_value=127,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(tx_i_dc_correction_setting, self.CALIBRATION)
|
self.add_setting(tx_i_dc_correction_setting, self.CALIBRATION)
|
||||||
|
|
||||||
tx_q_dc_correction_setting = IntSetting(self.TX_Q_DC_CORRECTION, 0, "Adjusts the direct current offset errors in the quadrature (Q) component of the transmit (TX) path.", min_value=-128, max_value=127, spin_box=(True, True))
|
tx_q_dc_correction_setting = IntSetting(
|
||||||
|
self.TX_Q_DC_CORRECTION,
|
||||||
|
0,
|
||||||
|
"Adjusts the direct current offset errors in the quadrature (Q) component of the transmit (TX) path.",
|
||||||
|
min_value=-128,
|
||||||
|
max_value=127,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(tx_q_dc_correction_setting, self.CALIBRATION)
|
self.add_setting(tx_q_dc_correction_setting, self.CALIBRATION)
|
||||||
|
|
||||||
tx_i_gain_correction_setting = IntSetting(self.TX_I_GAIN_CORRECTION, 2047, "Modifies the gain settings for the I channel of the TX path, adjusting for imbalances.", min_value=0, max_value=2047, spin_box=(True, True))
|
tx_i_gain_correction_setting = IntSetting(
|
||||||
|
self.TX_I_GAIN_CORRECTION,
|
||||||
|
2047,
|
||||||
|
"Modifies the gain settings for the I channel of the TX path, adjusting for imbalances.",
|
||||||
|
min_value=0,
|
||||||
|
max_value=2047,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(tx_i_gain_correction_setting, self.CALIBRATION)
|
self.add_setting(tx_i_gain_correction_setting, self.CALIBRATION)
|
||||||
|
|
||||||
tx_q_gain_correction_setting = IntSetting(self.TX_Q_GAIN_CORRECTION, 2039, "Modifies the gain settings for the Q channel of the TX path, adjusting for imbalances.", min_value=0, max_value=2047, spin_box=(True, True))
|
tx_q_gain_correction_setting = IntSetting(
|
||||||
|
self.TX_Q_GAIN_CORRECTION,
|
||||||
|
2039,
|
||||||
|
"Modifies the gain settings for the Q channel of the TX path, adjusting for imbalances.",
|
||||||
|
min_value=0,
|
||||||
|
max_value=2047,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(tx_q_gain_correction_setting, self.CALIBRATION)
|
self.add_setting(tx_q_gain_correction_setting, self.CALIBRATION)
|
||||||
|
|
||||||
tx_phase_adjustment_setting = IntSetting(self.TX_PHASE_ADJUSTMENT, 3, "Corrects the Phase of I Q signals in the TX path.", min_value=-2048, max_value=2047, spin_box=(True, True))
|
tx_phase_adjustment_setting = IntSetting(
|
||||||
|
self.TX_PHASE_ADJUSTMENT,
|
||||||
|
3,
|
||||||
|
"Corrects the Phase of I Q signals in the TX path.",
|
||||||
|
min_value=-2048,
|
||||||
|
max_value=2047,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(tx_phase_adjustment_setting, self.CALIBRATION)
|
self.add_setting(tx_phase_adjustment_setting, self.CALIBRATION)
|
||||||
|
|
||||||
rx_i_dc_correction_setting = IntSetting(self.RX_I_DC_CORRECTION, 0, "Adjusts the direct current offset errors in the in-phase (I) component of the receive (RX) path.", min_value=-63, max_value=63, spin_box=(True, True))
|
rx_i_dc_correction_setting = IntSetting(
|
||||||
|
self.RX_I_DC_CORRECTION,
|
||||||
|
0,
|
||||||
|
"Adjusts the direct current offset errors in the in-phase (I) component of the receive (RX) path.",
|
||||||
|
min_value=-63,
|
||||||
|
max_value=63,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(rx_i_dc_correction_setting, self.CALIBRATION)
|
self.add_setting(rx_i_dc_correction_setting, self.CALIBRATION)
|
||||||
|
|
||||||
rx_q_dc_correction_setting = IntSetting(self.RX_Q_DC_CORRECTION, 0, "Adjusts the direct current offset errors in the quadrature (Q) component of the receive (RX) path.", min_value=-63, max_value=63, spin_box=(True, True))
|
rx_q_dc_correction_setting = IntSetting(
|
||||||
|
self.RX_Q_DC_CORRECTION,
|
||||||
|
0,
|
||||||
|
"Adjusts the direct current offset errors in the quadrature (Q) component of the receive (RX) path.",
|
||||||
|
min_value=-63,
|
||||||
|
max_value=63,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(rx_q_dc_correction_setting, self.CALIBRATION)
|
self.add_setting(rx_q_dc_correction_setting, self.CALIBRATION)
|
||||||
|
|
||||||
rx_i_gain_correction_setting = IntSetting(self.RX_I_GAIN_CORRECTION, 2047, "Modifies the gain settings for the I channel of the RX path, adjusting for imbalances.", min_value=0, max_value=2047, spin_box=(True, True))
|
rx_i_gain_correction_setting = IntSetting(
|
||||||
|
self.RX_I_GAIN_CORRECTION,
|
||||||
|
2047,
|
||||||
|
"Modifies the gain settings for the I channel of the RX path, adjusting for imbalances.",
|
||||||
|
min_value=0,
|
||||||
|
max_value=2047,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(rx_i_gain_correction_setting, self.CALIBRATION)
|
self.add_setting(rx_i_gain_correction_setting, self.CALIBRATION)
|
||||||
|
|
||||||
rx_q_gain_correction_setting = IntSetting(self.RX_Q_GAIN_CORRECTION, 2047, "Modifies the gain settings for the Q channel of the RX path, adjusting for imbalances.", min_value=0, max_value=2047, spin_box=(True, True))
|
rx_q_gain_correction_setting = IntSetting(
|
||||||
|
self.RX_Q_GAIN_CORRECTION,
|
||||||
|
2047,
|
||||||
|
"Modifies the gain settings for the Q channel of the RX path, adjusting for imbalances.",
|
||||||
|
min_value=0,
|
||||||
|
max_value=2047,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(rx_q_gain_correction_setting, self.CALIBRATION)
|
self.add_setting(rx_q_gain_correction_setting, self.CALIBRATION)
|
||||||
|
|
||||||
rx_phase_adjustment_setting = IntSetting(self.RX_PHASE_ADJUSTMENT, 0, "Corrects the Phase of I Q signals in the RX path.", min_value=-2048, max_value=2047, spin_box=(True, True))
|
rx_phase_adjustment_setting = IntSetting(
|
||||||
|
self.RX_PHASE_ADJUSTMENT,
|
||||||
|
0,
|
||||||
|
"Corrects the Phase of I Q signals in the RX path.",
|
||||||
|
min_value=-2048,
|
||||||
|
max_value=2047,
|
||||||
|
spin_box=(True, True),
|
||||||
|
)
|
||||||
self.add_setting(rx_phase_adjustment_setting, self.CALIBRATION)
|
self.add_setting(rx_phase_adjustment_setting, self.CALIBRATION)
|
||||||
|
|
||||||
# Signal Processing settings
|
# Signal Processing settings
|
||||||
rx_offset_setting = FloatSetting(self.RX_OFFSET, 2.4e-6, "The offset of the RX event, this changes all the time")
|
rx_offset_setting = FloatSetting(
|
||||||
|
self.RX_OFFSET,
|
||||||
|
2.4e-6,
|
||||||
|
"The offset of the RX event, this changes all the time",
|
||||||
|
)
|
||||||
self.add_setting(rx_offset_setting, self.SIGNAL_PROCESSING)
|
self.add_setting(rx_offset_setting, self.SIGNAL_PROCESSING)
|
||||||
|
|
||||||
fft_shift_setting = BooleanSetting(self.FFT_SHIFT, False, "FFT shift")
|
fft_shift_setting = BooleanSetting(self.FFT_SHIFT, False, "FFT shift")
|
||||||
|
@ -147,6 +292,7 @@ class LimeNQRModel(BaseSpectrometerModel):
|
||||||
# Try to load the pulse programmer module
|
# Try to load the pulse programmer module
|
||||||
try:
|
try:
|
||||||
from nqrduck_pulseprogrammer.pulseprogrammer import pulse_programmer
|
from nqrduck_pulseprogrammer.pulseprogrammer import pulse_programmer
|
||||||
|
|
||||||
self.pulse_programmer = pulse_programmer
|
self.pulse_programmer = pulse_programmer
|
||||||
logger.debug("Pulse programmer found.")
|
logger.debug("Pulse programmer found.")
|
||||||
self.pulse_programmer.controller.on_loading(self.pulse_parameter_options)
|
self.pulse_programmer.controller.on_loading(self.pulse_parameter_options)
|
||||||
|
@ -157,6 +303,7 @@ class LimeNQRModel(BaseSpectrometerModel):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def target_frequency(self):
|
def target_frequency(self):
|
||||||
|
"""The target frequency of the spectrometer."""
|
||||||
return self._target_frequency
|
return self._target_frequency
|
||||||
|
|
||||||
@target_frequency.setter
|
@target_frequency.setter
|
||||||
|
@ -165,6 +312,7 @@ class LimeNQRModel(BaseSpectrometerModel):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def averages(self):
|
def averages(self):
|
||||||
|
"""The number of averages to be taken."""
|
||||||
return self._averages
|
return self._averages
|
||||||
|
|
||||||
@averages.setter
|
@averages.setter
|
||||||
|
@ -173,10 +321,9 @@ class LimeNQRModel(BaseSpectrometerModel):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def if_frequency(self):
|
def if_frequency(self):
|
||||||
|
"""The intermediate frequency to which the input signal is down converted during analog-to-digital conversion."""
|
||||||
return self._if_frequency
|
return self._if_frequency
|
||||||
|
|
||||||
@if_frequency.setter
|
@if_frequency.setter
|
||||||
def if_frequency(self, value):
|
def if_frequency(self, value):
|
||||||
self._if_frequency = value
|
self._if_frequency = value
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
"""View for LimeNQR spectrometer."""
|
||||||
from nqrduck_spectrometer.base_spectrometer_view import BaseSpectrometerView
|
from nqrduck_spectrometer.base_spectrometer_view import BaseSpectrometerView
|
||||||
|
|
||||||
|
|
||||||
class LimeNQRView(BaseSpectrometerView):
|
class LimeNQRView(BaseSpectrometerView):
|
||||||
|
"""View class for LimeNQR spectrometer."""
|
||||||
|
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
|
"""Initialize the LimeNQRView object."""
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
|
||||||
|
# Setting UI is automatically generated based on the settings specified in the model
|
||||||
self.widget = self.load_settings_ui()
|
self.widget = self.load_settings_ui()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue