From 1a6342e4cb3ee5a351547dc389873f9ce8f20a15 Mon Sep 17 00:00:00 2001 From: jupfi Date: Sat, 4 May 2024 21:55:43 +0200 Subject: [PATCH 1/3] Working RX dwelltime. --- .../controller.py | 31 ++++++++++++++++++ src/nqrduck_spectrometer_limenqr/model.py | 32 +++++++++++++------ 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/nqrduck_spectrometer_limenqr/controller.py b/src/nqrduck_spectrometer_limenqr/controller.py index b4db5e2..a478e6b 100644 --- a/src/nqrduck_spectrometer_limenqr/controller.py +++ b/src/nqrduck_spectrometer_limenqr/controller.py @@ -4,10 +4,12 @@ import logging import tempfile from pathlib import Path import numpy as np +from scipy.signal import resample, decimate from limedriver.binding import PyLimeConfig from limedriver.hdf_reader import HDF +from nqrduck.helpers.unitconverter import UnitConverter from nqrduck_spectrometer.base_spectrometer_controller import BaseSpectrometerController from nqrduck_spectrometer.measurement import Measurement from nqrduck_spectrometer.pulseparameters import TXPulse, RXReadout @@ -55,6 +57,29 @@ class LimeNQRController(BaseSpectrometerController): measurement_data = self.process_measurement_results(lime) + # Resample the RX data to the dwell time settings + dwell_time = self.module.model.get_setting_by_name( + self.module.model.RX_DWELL_TIME + ).value + dwell_time = UnitConverter.to_float(dwell_time) * 1e6 + logger.debug("Dwell time: %s", dwell_time) + logger.debug(f"Last tdx value: {measurement_data.tdx[-1]}") + if dwell_time: + n_data_points = int(measurement_data.tdx[-1] / dwell_time) + logger.debug("Resampling to %s data points", n_data_points) + tdx = np.linspace( + 0, measurement_data.tdx[-1], n_data_points, endpoint=False + ) + tdy = resample(measurement_data.tdy, n_data_points) + measurement_data = Measurement( + tdx, + tdy, + self.module.model.target_frequency, + IF_frequency=self.module.model.if_frequency, + ) + + + if measurement_data: self.emit_measurement_data(measurement_data) self.emit_status_message("Finished Measurement") @@ -456,6 +481,7 @@ class LimeNQRController(BaseSpectrometerController): parameter.get_option_by_name(TXPulse.RELATIVE_AMPLITUDE).value / 100 ) pulse_amplitude = np.clip(pulse_amplitude, -0.99, 0.99) + return pulse_shape, pulse_amplitude def modulate_pulse_amplitude( @@ -475,6 +501,11 @@ class LimeNQRController(BaseSpectrometerController): num_samples = int(float(event.duration) * lime.srate) tdx = np.linspace(0, float(event.duration), num_samples, endpoint=False) shift_signal = np.exp(1j * 2 * np.pi * self.module.model.if_frequency * tdx) + + # The pulse amplitude needs to be resampled to the number of samples + logger.debug("Resampling pulse amplitude to %s samples", num_samples) + pulse_amplitude = resample(pulse_amplitude, num_samples) + pulse_complex = pulse_amplitude * shift_signal modulated_amplitude = np.abs(pulse_complex) modulated_phase = self.unwrap_phase(np.angle(pulse_complex)) diff --git a/src/nqrduck_spectrometer_limenqr/model.py b/src/nqrduck_spectrometer_limenqr/model.py index 30dc5c5..1b59695 100644 --- a/src/nqrduck_spectrometer_limenqr/model.py +++ b/src/nqrduck_spectrometer_limenqr/model.py @@ -8,6 +8,7 @@ from nqrduck_spectrometer.settings import ( IntSetting, BooleanSetting, SelectionSetting, + StringSetting, ) logger = logging.getLogger(__name__) @@ -19,17 +20,18 @@ class LimeNQRModel(BaseSpectrometerModel): CHANNEL = "TX/RX Channel" TX_MATCHING = "TX Matching" RX_MATCHING = "RX Matching" - SAMPLING_FREQUENCY = "Sampling Frequency" - IF_FREQUENCY = "IF Frequency" - ACQUISITION_TIME = "Acquisition time" + SAMPLING_FREQUENCY = "Sampling Frequency (Hz)" + RX_DWELL_TIME = "RX Dwell Time (s)" + IF_FREQUENCY = "IF Frequency (Hz)" + ACQUISITION_TIME = "Acquisition time (s)" GATE_ENABLE = "Enable" GATE_PADDING_LEFT = "Gate padding left" GATE_PADDING_RIGHT = "Gate padding right" GATE_SHIFT = "Gate shift" RX_GAIN = "RX Gain" TX_GAIN = "TX Gain" - RX_LPF_BW = "RX LPF BW" - TX_LPF_BW = "TX LPF BW" + RX_LPF_BW = "RX LPF BW (Hz)" + TX_LPF_BW = "TX LPF BW (Hz)" TX_I_DC_CORRECTION = "TX I DC correction" TX_Q_DC_CORRECTION = "TX Q DC correction" TX_I_GAIN_CORRECTION = "TX I Gain correction" @@ -79,15 +81,27 @@ class LimeNQRModel(BaseSpectrometerModel): ) self.add_setting(rx_matching_setting, self.ACQUISITION) - sampling_frequency_setting = FloatSetting( + + sampling_frequency_options = [ + "30.72e6", + "15.36e6", + "7.68e6", + ] + sampling_frequency_setting = SelectionSetting( self.SAMPLING_FREQUENCY, - 30.72e6, + sampling_frequency_options, + "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) + rx_dwell_time_setting = StringSetting( + self.RX_DWELL_TIME, + "22n", + "The time between samples in the receive path.", + ) + self.add_setting(rx_dwell_time_setting, self.ACQUISITION) + if_frequency_setting = FloatSetting( self.IF_FREQUENCY, 5e6, From 1bceba1a0f57ce168564cadecb30152020ca509c Mon Sep 17 00:00:00 2001 From: jupfi Date: Sun, 5 May 2024 15:17:40 +0200 Subject: [PATCH 2/3] Added name to measurement. --- src/nqrduck_spectrometer_limenqr/controller.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/nqrduck_spectrometer_limenqr/controller.py b/src/nqrduck_spectrometer_limenqr/controller.py index a478e6b..dabbe5c 100644 --- a/src/nqrduck_spectrometer_limenqr/controller.py +++ b/src/nqrduck_spectrometer_limenqr/controller.py @@ -1,6 +1,7 @@ """Controller module for the Lime NQR spectrometer.""" import logging +from datetime import datetime import tempfile from pathlib import Path import numpy as np @@ -64,6 +65,7 @@ class LimeNQRController(BaseSpectrometerController): dwell_time = UnitConverter.to_float(dwell_time) * 1e6 logger.debug("Dwell time: %s", dwell_time) logger.debug(f"Last tdx value: {measurement_data.tdx[-1]}") + if dwell_time: n_data_points = int(measurement_data.tdx[-1] / dwell_time) logger.debug("Resampling to %s data points", n_data_points) @@ -71,15 +73,15 @@ class LimeNQRController(BaseSpectrometerController): 0, measurement_data.tdx[-1], n_data_points, endpoint=False ) tdy = resample(measurement_data.tdy, n_data_points) + name = measurement_data.name measurement_data = Measurement( + name, tdx, tdy, self.module.model.target_frequency, IF_frequency=self.module.model.if_frequency, ) - - if measurement_data: self.emit_measurement_data(measurement_data) self.emit_status_message("Finished Measurement") @@ -193,7 +195,11 @@ class LimeNQRController(BaseSpectrometerController): evidx = self.find_evaluation_range_indices(hdf, rx_begin, rx_stop) tdx, tdy = self.extract_measurement_data(lime, hdf, evidx) fft_shift = self.get_fft_shift() + # Measurement name date + module + target frequency + averages + sequence name + name = f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - LimeNQR - {self.module.model.target_frequency / 1e6} MHz - {self.module.model.averages} averages - {self.module.model.pulse_programmer.model.pulse_sequence.name}.quack" + logger.debug(f"Measurement name: {name}") return Measurement( + name, tdx, tdy, self.module.model.target_frequency, @@ -641,7 +647,7 @@ class LimeNQRController(BaseSpectrometerController): result ) # Reversed to maintain the original order if needed elsewhere - def translate_rx_event(self, lime : PyLimeConfig) -> tuple: + def translate_rx_event(self, lime: PyLimeConfig) -> tuple: """This method translates the RX event of the pulse sequence to the limr object. Args: @@ -702,7 +708,7 @@ class LimeNQRController(BaseSpectrometerController): previous_events = events[: events.index(rx_event)] return sum(event.duration for event in previous_events) - def calculate_offset(self, lime :PyLimeConfig) -> float: + def calculate_offset(self, lime: PyLimeConfig) -> float: """This method calculates the offset for the RX event. Args: From e9ba9626342daae8d5b34eae071aa07bdb8b071c Mon Sep 17 00:00:00 2001 From: jupfi Date: Sun, 5 May 2024 15:46:33 +0200 Subject: [PATCH 3/3] Version bump v0.0.6 --- CHANGELOG.md | 4 ++++ pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bcfa60..dc7d60f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Version 0.0.6 (05-05-2024) +- Added a dwell time setting for receiving. Additionally the sampling frequency is now settable. (`1a6342e4cb3ee5a351547dc389873f9ce8f20a15`) +- Measurements now have a name (`1bceba1a0f57ce168564cadecb30152020ca509c`) + ### Version 0.0.5 (26-04-2024) - Added support for the new formbuilder provided by the nqrduck core diff --git a/pyproject.toml b/pyproject.toml index a501aa2..cac27cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ allow-direct-references = true [project] name = "nqrduck-spectrometer-limenqr" -version = "0.0.5" +version = "0.0.6" authors = [ { name="jupfi", email="support@nqrduck.cool" }, ]