mirror of
https://github.com/nqrduck/nqrduck-spectrometer-limenqr.git
synced 2024-12-22 23:47:47 +00:00
Refactored start measurement method.
This commit is contained in:
parent
222e5fe252
commit
16aabe1ecc
1 changed files with 178 additions and 77 deletions
|
@ -16,94 +16,194 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
super().__init__(module)
|
super().__init__(module)
|
||||||
|
|
||||||
def start_measurement(self):
|
def start_measurement(self):
|
||||||
logger.debug(
|
self.log_start_message()
|
||||||
"Starting measurement with spectrometer: %s", self.module.model.name
|
|
||||||
)
|
|
||||||
# Now we request the pulse sequence set in the pulse programmer module
|
|
||||||
pulse_sequence = self.module.model.pulse_programmer.model.pulse_sequence
|
|
||||||
logger.debug("Pulse sequence is: %s", pulse_sequence.to_json())
|
|
||||||
|
|
||||||
try:
|
lime = self.initialize_lime()
|
||||||
from .contrib.limr import limr
|
if not lime:
|
||||||
|
|
||||||
self_path = Path(__file__).parent
|
|
||||||
driver_path = str(self_path / "contrib/pulseN_test_USB.cpp")
|
|
||||||
lime = limr(driver_path)
|
|
||||||
except ImportError as e:
|
|
||||||
logger.error("Error while importing limr. %s", e)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error("Error while loading pulseN_test_USB.cpp: %s", e)
|
|
||||||
|
|
||||||
lime.noi = -1 # No initialisation
|
|
||||||
lime.nrp = 1 # Numer of repetitions
|
|
||||||
|
|
||||||
lime = self.update_settings(lime)
|
|
||||||
lime = self.translate_pulse_sequence(lime)
|
|
||||||
|
|
||||||
|
|
||||||
lime.nav = self.module.model.averages
|
|
||||||
|
|
||||||
for key in sorted(lime.parsinp):
|
|
||||||
val = getattr(lime, key)
|
|
||||||
if val != []:
|
|
||||||
# logger.debug("Attribute: %s, Value: %s, Descr.: %s" % key, val, lime.parsinp[key][1])
|
|
||||||
logger.debug(key + ": " + str(val) + " " + lime.parsinp[key][1])
|
|
||||||
|
|
||||||
# Create temp folder for .hdf files
|
|
||||||
temp_dir = tempfile.TemporaryDirectory()
|
|
||||||
path = Path(temp_dir.name)
|
|
||||||
logger.debug("Created temporary directory: %s", path)
|
|
||||||
lime.spt = path
|
|
||||||
lime.fpa = "temp"
|
|
||||||
|
|
||||||
# Write to statusbar
|
|
||||||
self.module.nqrduck_signal.emit("statusbar_message", "Started Measurement")
|
|
||||||
|
|
||||||
logger.debug("Starting measurement")
|
|
||||||
lime.run()
|
|
||||||
|
|
||||||
logger.debug("Reading hdf file")
|
|
||||||
lime.readHDF()
|
|
||||||
|
|
||||||
rx_begin, rx_stop = self.translate_rx_event(lime)
|
|
||||||
logger.debug("RX event starts at: %s and ends at: %s", rx_begin, rx_stop)
|
|
||||||
|
|
||||||
# evaluation range, defines: blanking time and window length
|
|
||||||
evran = [rx_begin, rx_stop]
|
|
||||||
|
|
||||||
# np.where sometimes does not work out, so it is put in a try except
|
|
||||||
# always check the console for errors
|
|
||||||
try:
|
|
||||||
evidx = np.where((lime.HDF.tdx > evran[0]) & (lime.HDF.tdx < evran[1]))[0]
|
|
||||||
except:
|
|
||||||
logger.error("Error while reading the measurement data")
|
|
||||||
self.module.nqrduck_signal.emit("measurement_error", "Error with measurement data. Did you set an RX event?")
|
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
# time domain x and y data
|
self.setup_lime_parameters(lime)
|
||||||
tdx = lime.HDF.tdx[evidx] - lime.HDF.tdx[evidx][0]
|
self.setup_temporary_storage(lime)
|
||||||
tdy = lime.HDF.tdy[evidx] / lime.nav
|
|
||||||
|
|
||||||
fft_shift = self.module.model.get_setting_by_name(self.module.model.FFT_SHIFT).value
|
self.emit_status_message("Started Measurement")
|
||||||
|
|
||||||
if fft_shift:
|
if not self.perform_measurement(lime):
|
||||||
fft_shift = self.module.model.if_frequency
|
self.emit_status_message("Measurement failed")
|
||||||
|
self.emit_measurement_error("Error with measurement data. Did you set an RX event?")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
measurement_data = self.process_measurement_results(lime)
|
||||||
|
|
||||||
|
if measurement_data:
|
||||||
|
self.emit_measurement_data(measurement_data)
|
||||||
|
self.emit_status_message("Finished Measurement")
|
||||||
else:
|
else:
|
||||||
fft_shift = 0
|
self.emit_measurement_error("Measurement failed. Unable to retrieve data.")
|
||||||
|
|
||||||
measurement_data = Measurement(
|
def log_start_message(self):
|
||||||
tdx,
|
"""This method logs a message when the measurement is started."""
|
||||||
tdy,
|
logger.debug("Starting measurement with spectrometer: %s", self.module.model.name)
|
||||||
self.module.model.target_frequency,
|
|
||||||
frequency_shift=fft_shift,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Emit the data to the nqrduck core
|
def initialize_lime(self):
|
||||||
|
"""This method initializes the limr object that is used to communicate with the pulseN driver."""
|
||||||
|
try:
|
||||||
|
from .contrib.limr import limr
|
||||||
|
driver_path = str(Path(__file__).parent / "contrib/pulseN_test_USB.cpp")
|
||||||
|
return limr(driver_path)
|
||||||
|
except ImportError as e:
|
||||||
|
logger.error("Error while importing limr: %s", e)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Error while initializing Lime driver: %s", e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def setup_lime_parameters(self, lime):
|
||||||
|
"""This method sets the parameters of the limr object according to the settings set in the spectrometer module.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lime (limr): The limr object that is used to communicate with the pulseN driver
|
||||||
|
"""
|
||||||
|
lime.noi = -1
|
||||||
|
lime.nrp = 1
|
||||||
|
lime = self.update_settings(lime)
|
||||||
|
lime = self.translate_pulse_sequence(lime)
|
||||||
|
lime.nav = self.module.model.averages
|
||||||
|
self.log_lime_parameters(lime)
|
||||||
|
|
||||||
|
def setup_temporary_storage(self, lime):
|
||||||
|
"""This method sets up the temporary storage for the measurement data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lime (limr): The limr object that is used to communicate with the pulseN driver
|
||||||
|
"""
|
||||||
|
temp_dir = tempfile.TemporaryDirectory()
|
||||||
|
logger.debug("Created temporary directory at: %s", temp_dir.name)
|
||||||
|
lime.spt = Path(temp_dir.name) # Temporary storage path
|
||||||
|
lime.fpa = "temp" # Temporary filename prefix or related config
|
||||||
|
|
||||||
|
def perform_measurement(self, lime):
|
||||||
|
"""This method executes the measurement procedure.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lime (limr): The limr object that is used to communicate with the pulseN driver
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if the measurement was successful, False otherwise
|
||||||
|
"""
|
||||||
|
logger.debug("Running the measurement procedure")
|
||||||
|
try:
|
||||||
|
lime.run()
|
||||||
|
lime.readHDF()
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Failed to execute the measurement: %s", e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def process_measurement_results(self, lime):
|
||||||
|
"""This method processes the measurement results and returns a Measurement object.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lime (limr): The limr object that is used to communicate with the pulseN driver
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Measurement: The measurement data
|
||||||
|
"""
|
||||||
|
rx_begin, rx_stop = self.translate_rx_event(lime)
|
||||||
|
if rx_begin is None or rx_stop is None:
|
||||||
|
return None
|
||||||
|
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)
|
||||||
|
|
||||||
|
def calculate_measurement_data(self, lime, rx_begin, rx_stop):
|
||||||
|
"""This method calculates the measurement data from the limr object.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lime (limr): The limr object that is used to communicate with the pulseN driver
|
||||||
|
rx_begin (float): The start time of the RX event in µs
|
||||||
|
rx_stop (float): The stop time of the RX event in µs
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Measurement: The measurement data
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
evidx = self.find_evaluation_range_indices(lime, rx_begin, rx_stop)
|
||||||
|
tdx, tdy = self.extract_measurement_data(lime, evidx)
|
||||||
|
fft_shift = self.get_fft_shift()
|
||||||
|
return Measurement(tdx, tdy, self.module.model.target_frequency, frequency_shift=fft_shift)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Error processing measurement result: %s", e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def find_evaluation_range_indices(self, lime, rx_begin, rx_stop):
|
||||||
|
"""This method finds the indices of the evaluation range in the measurement data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lime (limr): The limr object that is used to communicate with the pulseN driver
|
||||||
|
rx_begin (float): The start time of the RX event in µs
|
||||||
|
rx_stop (float): The stop time of the RX event in µs
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: The indices of the evaluation range in the measurement data"""
|
||||||
|
return np.where((lime.HDF.tdx > rx_begin) & (lime.HDF.tdx < rx_stop))[0]
|
||||||
|
|
||||||
|
def extract_measurement_data(self, lime, indices):
|
||||||
|
"""This method extracts the measurement data from the limr object.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lime (limr): The limr object that is used to communicate with the pulseN driver
|
||||||
|
indices (list): The indices of the evaluation range in the measurement data
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: A tuple containing the time vector and the measurement data
|
||||||
|
"""
|
||||||
|
tdx = lime.HDF.tdx[indices] - lime.HDF.tdx[indices][0]
|
||||||
|
tdy = lime.HDF.tdy[indices] / lime.nav
|
||||||
|
return tdx, tdy
|
||||||
|
|
||||||
|
def get_fft_shift(self):
|
||||||
|
"""This method returns the FFT shift value from the settings.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: The 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
|
||||||
|
|
||||||
|
def emit_measurement_data(self, measurement_data):
|
||||||
|
"""This method emits the measurement data to the GUI.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
measurement_data (Measurement): The measurement data
|
||||||
|
"""
|
||||||
logger.debug("Emitting measurement data")
|
logger.debug("Emitting measurement data")
|
||||||
self.module.nqrduck_signal.emit("statusbar_message", "Finished Measurement")
|
|
||||||
|
|
||||||
self.module.nqrduck_signal.emit("measurement_data", measurement_data)
|
self.module.nqrduck_signal.emit("measurement_data", measurement_data)
|
||||||
|
|
||||||
|
def emit_status_message(self, message):
|
||||||
|
"""This method emits a status message to the GUI.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): The status message
|
||||||
|
"""
|
||||||
|
self.module.nqrduck_signal.emit("statusbar_message", message)
|
||||||
|
|
||||||
|
def emit_measurement_error(self, error_message):
|
||||||
|
"""This method emits a measurement error to the GUI.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
error_message (str): The error message
|
||||||
|
"""
|
||||||
|
logger.error(error_message)
|
||||||
|
self.module.nqrduck_signal.emit("measurement_error", error_message)
|
||||||
|
|
||||||
|
def log_lime_parameters(self, lime):
|
||||||
|
"""This method logs the parameters of the limr object.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lime (limr): The limr object that is used to communicate with the pulseN driver
|
||||||
|
"""
|
||||||
|
for key in sorted(lime.parsinp):
|
||||||
|
val = getattr(lime, key, [])
|
||||||
|
if val:
|
||||||
|
logger.debug(f"{key}: {val} {lime.parsinp[key][1]}")
|
||||||
|
|
||||||
def update_settings(self, lime):
|
def update_settings(self, lime):
|
||||||
"""This method sets the parameters of the limr object according to the settings set in the spectrometer module.
|
"""This method sets the parameters of the limr object according to the settings set in the spectrometer module.
|
||||||
|
|
||||||
|
@ -118,6 +218,7 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
self.module.model.name,
|
self.module.model.name,
|
||||||
)
|
)
|
||||||
lime.t3d = [0, 0, 0, 0]
|
lime.t3d = [0, 0, 0, 0]
|
||||||
|
# I don't like this code
|
||||||
for category in self.module.model.settings.keys():
|
for category in self.module.model.settings.keys():
|
||||||
for setting in self.module.model.settings[category]:
|
for setting in self.module.model.settings[category]:
|
||||||
logger.debug("Setting %s has value %s", setting.name, setting.value)
|
logger.debug("Setting %s has value %s", setting.name, setting.value)
|
||||||
|
|
Loading…
Reference in a new issue