mirror of
https://github.com/nqrduck/nqrduck-spectrometer-limenqr.git
synced 2024-11-09 11:10:03 +00:00
Started pulse sequence translation.
This commit is contained in:
parent
c4b70065e0
commit
ecd779ed1f
4 changed files with 129 additions and 53 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -19,4 +19,8 @@ build/
|
|||
venv/
|
||||
|
||||
# Other
|
||||
*.DS_Store
|
||||
*.DS_Store
|
||||
|
||||
# Contrib files without permission
|
||||
src/nqrduck_spectrometer_limenqr/contrib/limr.py
|
||||
src/nqrduck_spectrometer_limenqr/contrib/pulseN_test_USB.cpp
|
0
src/nqrduck_spectrometer_limenqr/contrib/__init__.py
Normal file
0
src/nqrduck_spectrometer_limenqr/contrib/__init__.py
Normal file
|
@ -1,4 +1,6 @@
|
|||
import logging
|
||||
from pathlib import Path
|
||||
import numpy as np
|
||||
from nqrduck.module.module_controller import ModuleController
|
||||
from nqrduck_spectrometer.base_spectrometer_controller import BaseSpectrometerController
|
||||
|
||||
|
@ -10,3 +12,90 @@ class LimeNQRController(BaseSpectrometerController):
|
|||
|
||||
def start_measurement(self):
|
||||
logger.debug("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.dump_sequence_data())
|
||||
|
||||
try:
|
||||
from .contrib.limr import limr
|
||||
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 = self.update_settings(lime)
|
||||
lime = self.translate_pulse_sequence(lime)
|
||||
|
||||
def update_settings(self, lime):
|
||||
logger.debug("Updating settings for spectrometer: %s for measurement", self.module.model.name)
|
||||
l.t3d = [0, 0, 0, 0]
|
||||
for category in self.module.model.settings.keys():
|
||||
for setting in self.module.model.settings[category]:
|
||||
logger.debug("Setting %s has value %s", setting.name, setting.value)
|
||||
if setting.name == "RX Gain":
|
||||
lime.rgn = setting.value
|
||||
elif setting.name == "TX Gain":
|
||||
lime.tgn = setting.value
|
||||
elif setting.name == "Averages":
|
||||
lime.nav = setting.value
|
||||
elif setting.name == "Sampling Frequency":
|
||||
lime.sra = setting.value
|
||||
elif setting.name == "RX LPF BW":
|
||||
lime.rlp = setting.value
|
||||
elif setting.name == "TX LPF BW":
|
||||
lime.tlp = setting.value
|
||||
elif setting.name == "IF frequency":
|
||||
lime.lof = self.target_frequency - setting.value
|
||||
elif setting.name == "Acquisition time":
|
||||
lime.tac = 82e-6
|
||||
elif setting.name == "Enable":
|
||||
lime.t3d[0] = int(setting.value)
|
||||
elif setting.name == "Gate padding left":
|
||||
lime.t3d[1] = setting.value
|
||||
elif setting.name == "Gate shift":
|
||||
lime.t3d[2] = setting.value
|
||||
elif setting.name == "Gate padding right":
|
||||
lime.t3d[3] = setting.value
|
||||
|
||||
return lime
|
||||
|
||||
def translate_pulse_sequence(self, lime):
|
||||
"""This method translates the pulse sequence into the format required by the lime spectrometer.
|
||||
"""
|
||||
|
||||
for event in self.module.model.pulse_programmer.model.pulse_sequence.events.values():
|
||||
logger.debug("Event %s has parameters: %s", event.name, event.parameters)
|
||||
for parameter in event.parameters.values():
|
||||
logger.debug("Parameter %s has options: %s", parameter.name, parameter.options)
|
||||
|
||||
if parameter.name == "TX":
|
||||
|
||||
if len(lime.pfr) == 0:
|
||||
# Add the TX pulse to the pulse frequency list (lime.pfr)
|
||||
lime.pfr = [self.module.model.if_frequency]
|
||||
# Add the duration of the TX pulse to the pulse duration list (lime.pdr)
|
||||
lime.pdr = [event.duration]
|
||||
# Add the TX pulse amplitude to the pulse amplitude list (lime.pam)
|
||||
lime.pam = [parameter.options["TX Amplitude"].value]
|
||||
# Add the pulse offset to the pulse offset list (lime.pof)
|
||||
# This leads to a default offset of 300 samples for the first pulse
|
||||
lime.pof = [300]
|
||||
# Add the TX pulse phase to the pulse phase list (lime.pph) -> not yet implemented
|
||||
else:
|
||||
lime.pfr.append(self.module.model.if_frequency)
|
||||
lime.pdr.append(event.duration)
|
||||
lime.pam.append(parameter.options["TX Amplitude"].value)
|
||||
lime.pof.append(np.ceil(lime.pfr[-2] * lime.sra))
|
||||
|
||||
# The acquisition time can be calculated from the buffer length of 4096 samples and the sampling frequency
|
||||
# 82µs is the shortest possible acquisition time
|
||||
|
||||
# The last event is the repetition time event
|
||||
lime.trp = event.duration
|
||||
|
||||
lime.npu = len(lime.pfr)
|
||||
return lime
|
||||
|
|
@ -10,18 +10,42 @@ class LimeNQRModel(BaseSpectrometerModel):
|
|||
|
||||
def __init__(self, module) -> None:
|
||||
super().__init__(module)
|
||||
self.add_setting("Frequency", 100, "Experiment frequency", "Acquisition")
|
||||
# Acquisition settings
|
||||
self.add_setting("Frequency", 100e6, "Experiment frequency", "Acquisition")
|
||||
self.target_frequency = 100e6
|
||||
self.add_setting("Averages", 100, "Number of averages", "Acquisition")
|
||||
self.add_setting("Sampling Frequency", 30.72e6 , "Sampling frequency", "Acquisition")
|
||||
self.add_setting("IF Frequency", 1.2e6, "IF frequency", "Acquisition")
|
||||
self.if_frequency = 1.2e6
|
||||
self.add_setting("Acquisition time", 82e-6, "Acquisition time - this is from the beginning of the pulse sequence", "Acquisition")
|
||||
# Gate Settings
|
||||
self.add_setting("Enable", True, "Enable", "Gate Settings")
|
||||
self.add_setting("Gate padding left", 10, "Gate padding left", "Gate Settings")
|
||||
self.add_setting("Gate padding right", 10, "Gate padding right", "Gate Settings")
|
||||
self.add_setting("Gate shift", 53, "Gate shift", "Gate Settings")
|
||||
# RX/TX settings
|
||||
self.add_setting("RX Gain", 55, "RX Gain", "RX/TX Settings")
|
||||
self.add_setting("TX Gain", 40, "TX Gain", "RX/TX Settings")
|
||||
self.add_setting("RX LPF BW", 30.72e6/2, "RX LPF BW", "RX/TX Settings")
|
||||
self.add_setting("TX LPF BW", 130.0e6, "TX LPF BW", "RX/TX Settings")
|
||||
# Calibration settings
|
||||
self.add_setting("TX I DC correction", -45, "TX I DC correction", "Calibration")
|
||||
self.add_setting("TX Q DC correction", 0, "TX Q DC correction", "Calibration")
|
||||
self.add_setting("TX I Gain correction", 2047, "TX I Gain correction", "Calibration")
|
||||
self.add_setting("TX Q Gain correction", 2039, "TX Q Gain correction", "Calibration")
|
||||
self.add_setting("TX phase adjustment", 3, "TX phase adjustment", "Calibration")
|
||||
self.add_setting("RX I DC correction", 0, "TX I DC correction", "Calibration")
|
||||
self.add_setting("RX Q DC correction", 0, "TX Q DC correction", "Calibration")
|
||||
self.add_setting("RX I Gain correction", 2047, "TX I Gain correction", "Calibration")
|
||||
self.add_setting("RX Q Gain correction", 2047, "TX Q Gain correction", "Calibration")
|
||||
self.add_setting("RX phase adjustment", 0, "TX phase adjustment", "Calibration")
|
||||
|
||||
# Pulse parameter options
|
||||
self.add_pulse_parameter_option("TX", TXPulse)
|
||||
self.add_pulse_parameter_option("Gate", Gate)
|
||||
self.add_pulse_parameter_option("RX", RXReadout)
|
||||
|
||||
# Try to load the pulse programmer module
|
||||
try:
|
||||
from nqrduck_pulseprogrammer.pulseprogrammer import pulse_programmer
|
||||
self.pulse_programmer = pulse_programmer
|
||||
|
@ -31,60 +55,19 @@ class LimeNQRModel(BaseSpectrometerModel):
|
|||
logger.warning("No pulse programmer found.")
|
||||
|
||||
@property
|
||||
def rx_antenna(self):
|
||||
return self._rx_antenna
|
||||
def target_frequency(self):
|
||||
return self._target_frequency
|
||||
|
||||
@rx_antenna.setter
|
||||
def rx_antenna(self, value):
|
||||
self._rx_antenna = value
|
||||
@target_frequency.setter
|
||||
def target_frequency(self, value):
|
||||
self._target_frequency = value
|
||||
|
||||
@property
|
||||
def tx_antenna(self):
|
||||
return self._tx_antenna
|
||||
def if_frequency(self):
|
||||
return self._if_frequency
|
||||
|
||||
@tx_antenna.setter
|
||||
def tx_antenna(self, value):
|
||||
self._tx_antenna = value
|
||||
@if_frequency.setter
|
||||
def if_frequency(self, value):
|
||||
self._if_frequency = value
|
||||
|
||||
@property
|
||||
def rx_gain(self):
|
||||
return self._rx_gain
|
||||
|
||||
@rx_gain.setter
|
||||
def rx_gain(self, value):
|
||||
self._rx_gain = value
|
||||
|
||||
@property
|
||||
def tx_gain(self):
|
||||
return self._tx_gain
|
||||
|
||||
@tx_gain.setter
|
||||
def tx_gain(self, value):
|
||||
self._tx_gain = value
|
||||
|
||||
@property
|
||||
def rx_lpfbw(self):
|
||||
return self._rx_lpfbw
|
||||
|
||||
@rx_lpfbw.setter
|
||||
def rx_lpfbw(self, value):
|
||||
self._rx_lpfbw = value
|
||||
|
||||
@property
|
||||
def tx_lpfbw(self):
|
||||
return self._tx_lpfbw
|
||||
|
||||
@tx_lpfbw.setter
|
||||
def tx_lpfbw(self, value):
|
||||
self._tx_lpfbw = value
|
||||
|
||||
# Pulse params
|
||||
|
||||
@property
|
||||
def tx_freq(self):
|
||||
return self._tx_freq
|
||||
|
||||
@tx_freq.setter
|
||||
def tx_freq(self, value):
|
||||
self._tx_freq = value
|
||||
|
||||
|
|
Loading…
Reference in a new issue