Added table option for phase cycling readout scheme.

This commit is contained in:
jupfi 2024-06-07 17:30:11 +02:00
parent 0b7c6085f0
commit f11dcbd15f
5 changed files with 66 additions and 37 deletions

View file

@ -232,3 +232,39 @@ class FunctionOption(Option):
obj = cls(data["name"], functions) obj = cls(data["name"], functions)
obj.value = Function.from_json(data["value"]) obj.value = Function.from_json(data["value"])
return obj return obj
class TableOption(Option):
"""A table option has rows and columns and can be used to store a table of values. The value is a list of lists."""
def __init__(self, name: str, value) -> None:
"""Initializes the table option."""
super().__init__(name, value)
def set_value(self, value):
"""Sets the value of the option."""
self.value = value
def to_json(self):
"""Returns a json representation of the option.
Returns:
dict: The json representation of the option.
"""
return {
"name": self.name,
"value": self.value,
"class": self.__class__.__name__,
}
@classmethod
def from_json(cls, data):
"""Creates a TableOption from a json representation.
Args:
data (dict): The json representation of the TableOption.
Returns:
TableOption: The TableOption.
"""
obj = cls(data["name"], data["value"])
return obj

View file

@ -184,27 +184,6 @@ class PhaseTable:
def phase_array(self, phase_array : np.array): def phase_array(self, phase_array : np.array):
self._phase_array = phase_array self._phase_array = phase_array
@property
def rx_phase_sign(self) -> list:
return self._rx_phase_sign
@rx_phase_sign.setter
def rx_phase_sign(self, rx_phase_sign: list):
"""The phase sign of the RX pulse.
Args:
rx_phase_sign (list): A list of phase signs for the RX pulse. The different entries are tuples with the first element being the sign and the second element being the phase.
"""
# Check that the rx_phase_sign has the same length as the number of rows in the phase table
if len(rx_phase_sign) != self.phase_array.shape[0]:
raise ValueError(
f"The number of rows in the phase table is {self.phase_table.shape[0]} but the length of the rx_phase_sign is {len(rx_phase_sign)}"
)
self._rx_phase_sign = rx_phase_sign
@property @property
def n_phase_cycles(self) -> int: def n_phase_cycles(self) -> int:
return self.phase_array.shape[0] return self.phase_array.shape[0]

View file

@ -10,7 +10,13 @@ import logging
import numpy as np import numpy as np
from numpy.core.multiarray import array as array from numpy.core.multiarray import array as array
from quackseq.options import BooleanOption, FunctionOption, NumericOption, Option from quackseq.options import (
BooleanOption,
FunctionOption,
NumericOption,
Option,
TableOption,
)
from quackseq.functions import ( from quackseq.functions import (
RectFunction, RectFunction,
SincFunction, SincFunction,
@ -163,7 +169,7 @@ class RXReadout(PulseParameter):
""" """
RX = "Enable RX Readout" RX = "Enable RX Readout"
PHASE = "RX Phase (°)" READOUT_SCHEME = "Readout Scheme"
def __init__(self, name) -> None: def __init__(self, name) -> None:
"""Initializes the RX Readout PulseParameter. """Initializes the RX Readout PulseParameter.
@ -173,10 +179,8 @@ class RXReadout(PulseParameter):
super().__init__(name) super().__init__(name)
self.add_option(BooleanOption(self.RX, False)) self.add_option(BooleanOption(self.RX, False))
# Receiver Phase # Readout Scheme for phase cycling - default is a positive sign with a 0 phase
self.add_option( self.add_option(TableOption(self.READOUT_SCHEME, [[1, 0]]))
NumericOption(self.PHASE, 0, min_value=0, max_value=360, is_float=True)
)
class Gate(PulseParameter): class Gate(PulseParameter):

View file

@ -260,7 +260,7 @@ class QuackSequence(PulseSequence):
self.set_tx_phase(event, phase) self.set_tx_phase(event, phase)
self.set_tx_shape(event, shape) self.set_tx_shape(event, shape)
def add_readout_event(self, event_name: str, duration: float, phase: float = 0): def add_readout_event(self, event_name: str, duration: float):
"""Adds a readout event to the pulse sequence. """Adds a readout event to the pulse sequence.
Args: Args:
@ -269,7 +269,6 @@ class QuackSequence(PulseSequence):
""" """
event = self.create_event(event_name, duration) event = self.create_event(event_name, duration)
self.set_rx(event, True) self.set_rx(event, True)
self.set_rx_phase(event, phase)
# TX Specific functions # TX Specific functions
@ -344,13 +343,24 @@ class QuackSequence(PulseSequence):
""" """
event.parameters[self.RX_READOUT].get_option_by_name(RXReadout.RX).value = rx event.parameters[self.RX_READOUT].get_option_by_name(RXReadout.RX).value = rx
def set_rx_phase(self, event, phase: float) -> None: def set_rx_readout_scheme(self, event, readout_scheme: list) -> None:
"""Sets the phase of the receiver. """Sets the readout scheme of the receiver.
Args: Args:
event (Event): The event to set the phase for event (Event): The event to set the readout scheme for
phase (float): The phase of the receiver readout_scheme (list): The readout scheme of the receiver
""" """
# Check that the readout scheme is valid
self.phase_table.update_phase_array()
n_cycles = self.phase_table.n_phase_cycles
rows = len(readout_scheme)
if rows != n_cycles:
raise ValueError(
f"Readout scheme needs to have {n_cycles} cycles, but has {rows}"
)
event.parameters[self.RX_READOUT].get_option_by_name( event.parameters[self.RX_READOUT].get_option_by_name(
RXReadout.PHASE RXReadout.READOUT_SCHEME
).value = phase ).value = readout_scheme

View file

@ -55,12 +55,12 @@ class SpectrometerController:
[event.duration for event in previous_events] [event.duration for event in previous_events]
) )
rx_duration = event.duration rx_duration = event.duration
phase = parameter.get_option_by_name(RXReadout.PHASE).value readout_scheme = parameter.get_option_by_name(RXReadout.READOUT_SCHEME).value
rx_begin = float(previous_events_duration) rx_begin = float(previous_events_duration)
if rx_duration: if rx_duration:
rx_stop = rx_begin + float(rx_duration) rx_stop = rx_begin + float(rx_duration)
return rx_begin * 1e6, rx_stop * 1e6, phase return rx_begin * 1e6, rx_stop * 1e6, readout_scheme
else: else:
return None, None, None return None, None, None