Merge pull request #12 from nqrduck/RX-dwelltime

Rx dwelltime
This commit is contained in:
Julia P 2024-05-05 15:46:49 +02:00 committed by GitHub
commit 03d5571b59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 67 additions and 12 deletions

View file

@ -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

View file

@ -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" },
]

View file

@ -1,13 +1,16 @@
"""Controller module for the Lime NQR spectrometer."""
import logging
from datetime import datetime
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 +58,30 @@ 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)
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")
@ -168,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,
@ -456,6 +487,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 +507,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))
@ -610,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:
@ -671,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:

View file

@ -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,