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/
|
venv/
|
||||||
|
|
||||||
# Other
|
# 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
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
import numpy as np
|
||||||
from nqrduck.module.module_controller import ModuleController
|
from nqrduck.module.module_controller import ModuleController
|
||||||
from nqrduck_spectrometer.base_spectrometer_controller import BaseSpectrometerController
|
from nqrduck_spectrometer.base_spectrometer_controller import BaseSpectrometerController
|
||||||
|
|
||||||
|
@ -10,3 +12,90 @@ class LimeNQRController(BaseSpectrometerController):
|
||||||
|
|
||||||
def start_measurement(self):
|
def start_measurement(self):
|
||||||
logger.debug("Starting measurement with spectrometer: %s", self.module.model.name)
|
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:
|
def __init__(self, module) -> None:
|
||||||
super().__init__(module)
|
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("Averages", 100, "Number of averages", "Acquisition")
|
||||||
self.add_setting("Sampling Frequency", 30.72e6 , "Sampling frequency", "Acquisition")
|
self.add_setting("Sampling Frequency", 30.72e6 , "Sampling frequency", "Acquisition")
|
||||||
self.add_setting("IF Frequency", 1.2e6, "IF 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("RX Gain", 55, "RX Gain", "RX/TX Settings")
|
||||||
self.add_setting("TX Gain", 40, "TX 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("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")
|
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("TX", TXPulse)
|
||||||
self.add_pulse_parameter_option("Gate", Gate)
|
self.add_pulse_parameter_option("Gate", Gate)
|
||||||
self.add_pulse_parameter_option("RX", RXReadout)
|
self.add_pulse_parameter_option("RX", RXReadout)
|
||||||
|
|
||||||
|
# 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
|
||||||
|
@ -31,60 +55,19 @@ class LimeNQRModel(BaseSpectrometerModel):
|
||||||
logger.warning("No pulse programmer found.")
|
logger.warning("No pulse programmer found.")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rx_antenna(self):
|
def target_frequency(self):
|
||||||
return self._rx_antenna
|
return self._target_frequency
|
||||||
|
|
||||||
@rx_antenna.setter
|
@target_frequency.setter
|
||||||
def rx_antenna(self, value):
|
def target_frequency(self, value):
|
||||||
self._rx_antenna = value
|
self._target_frequency = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tx_antenna(self):
|
def if_frequency(self):
|
||||||
return self._tx_antenna
|
return self._if_frequency
|
||||||
|
|
||||||
@tx_antenna.setter
|
@if_frequency.setter
|
||||||
def tx_antenna(self, value):
|
def if_frequency(self, value):
|
||||||
self._tx_antenna = 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