Added block event creation.

This commit is contained in:
jupfi 2024-05-29 08:26:21 +02:00
parent f4ac146611
commit e504f0154d
3 changed files with 88 additions and 49 deletions

View file

@ -1,7 +1,6 @@
import logging import logging
from collections import OrderedDict from collections import OrderedDict
from quackseq.pulsesequence import PulseSequence
from quackseq.pulseparameters import Option from quackseq.pulseparameters import Option
from quackseq.helpers import UnitConverter from quackseq.helpers import UnitConverter
@ -13,7 +12,7 @@ class Event:
Args: Args:
name (str): The name of the event name (str): The name of the event
duration (str): The duration of the event duration (float | str): The duration of the event, either as a float or a string with a unit suffix (n, u, m)
pulse_sequence (PulseSequence): The pulse sequence the event belongs to pulse_sequence (PulseSequence): The pulse sequence the event belongs to
Attributes: Attributes:
@ -22,7 +21,7 @@ class Event:
pulse_sequence (PulseSequence): The pulse sequence the event belongs to pulse_sequence (PulseSequence): The pulse sequence the event belongs to
""" """
def __init__(self, name: str, duration: str, pulse_sequence : PulseSequence) -> None: def __init__(self, name: str, duration: float | str, pulse_sequence : "PulseSequence") -> None:
"""Initializes the event.""" """Initializes the event."""
self.parameters = OrderedDict() self.parameters = OrderedDict()
self.name = name self.name = name
@ -46,15 +45,6 @@ class Event:
id(self.parameters[name]), id(self.parameters[name]),
) )
def on_duration_changed(self, duration: str) -> None:
"""This method is called when the duration of the event is changed.
Args:
duration (str): The new duration of the event
"""
logger.debug("Duration of event %s changed to %s", self.name, duration)
self.duration = duration
@classmethod @classmethod
def load_event(cls, event, pulse_parameter_options): def load_event(cls, event, pulse_parameter_options):
"""Loads an event from a dict. """Loads an event from a dict.
@ -95,12 +85,11 @@ class Event:
return self._duration return self._duration
@duration.setter @duration.setter
def duration(self, duration: str): def duration(self, duration: float | str):
# Duration needs to be a positive number # Duration needs to be a positive number
try: if isinstance(duration, str):
duration = UnitConverter.to_float(duration) duration = UnitConverter.to_float(duration)
except ValueError:
raise ValueError("Duration needs to be a number")
if duration < 0: if duration < 0:
raise ValueError("Duration needs to be a positive number") raise ValueError("Duration needs to be a positive number")

View file

@ -5,7 +5,8 @@ import importlib.metadata
from collections import OrderedDict from collections import OrderedDict
from quackseq.pulseparameters import PulseParameter, TXPulse, RXReadout from quackseq.pulseparameters import PulseParameter, TXPulse, RXReadout
from quackseq.functions import Function from quackseq.functions import Function, RectFunction
from quackseq.event import Event
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -60,19 +61,24 @@ class PulseSequence:
Args: Args:
event (Event): The event to add event (Event): The event to add
""" """
if event.name in self.get_event_names():
raise ValueError(f"Event with name {event.name} already exists in the pulse sequence")
self.events.append(event) self.events.append(event)
def create_event(self, event_name: str, duration: float) -> "Event": def create_event(self, event_name: str, duration: str) -> "Event":
"""Create a new event and return it. """Create a new event and return it.
Args: Args:
event_name (str): The name of the event event_name (str): The name of the event with a unit suffix (n, u, m)
duration (float): The duration of the event duration (float): The duration of the event
Returns: Returns:
Event: The created event Event: The created event
""" """
event = self.Event(event_name, f"{float(duration):.16g}u") event = Event(event_name, duration, self)
if event.name in self.get_event_names():
raise ValueError(f"Event with name {event.name} already exists in the pulse sequence")
self.events.append(event) self.events.append(event)
return event return event
@ -215,6 +221,26 @@ class QuackSequence(PulseSequence):
self.add_pulse_parameter_option(self.TX_PULSE, TXPulse) self.add_pulse_parameter_option(self.TX_PULSE, TXPulse)
self.add_pulse_parameter_option(self.RX_READOUT, RXReadout) self.add_pulse_parameter_option(self.RX_READOUT, RXReadout)
def add_blank_event(self, event_name: str, duration: float):
event = self.create_event(event_name, duration)
def add_pulse_event(
self,
event_name: str,
duration: float,
amplitude: float,
phase: float,
shape: Function = RectFunction(),
):
event = self.create_event(event_name, duration)
self.set_tx_amplitude(event, amplitude)
self.set_tx_phase(event, phase)
self.set_tx_shape(event, shape)
def add_readout_event(self, event_name: str, duration: float):
event = self.create_event(event_name, duration)
self.set_rx(event, True)
# TX Specific functions # TX Specific functions
def set_tx_amplitude(self, event, amplitude: float) -> None: def set_tx_amplitude(self, event, amplitude: float) -> None:
@ -259,6 +285,4 @@ class QuackSequence(PulseSequence):
event (Event): The event to set the receiver for event (Event): The event to set the receiver for
rx (bool): The receiver state rx (bool): The receiver state
""" """
event.parameters[self.RX_READOUT].get_option_by_name( event.parameters[self.RX_READOUT].get_option_by_name(RXReadout.RX).value = rx
RXReadout.RX
).value = rx

View file

@ -1,52 +1,78 @@
# Dummy test to communicate the structure import unittest
import logging import logging
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from quackseq.pulsesequence import QuackSequence from quackseq.pulsesequence import QuackSequence
from quackseq.event import Event from quackseq.event import Event
from quackseq.functions import RectFunction from quackseq.functions import RectFunction
from quackseq.spectrometer.simulator import Simulator from quackseq.spectrometer.simulator import Simulator
logging.basicConfig(level=logging.DEBUG) # logging.basicConfig(level=logging.DEBUG)
seq = QuackSequence("test")
tx = Event("tx", "10u", seq) class TestQuackSequence(unittest.TestCase):
seq.add_event(tx) def test_event_creation(self):
seq = QuackSequence("test - event creation")
seq.set_tx_amplitude(tx, 1) seq.add_pulse_event("tx", "10u", 1, 0, RectFunction())
seq.set_tx_phase(tx, 0) seq.add_blank_event("blank", "3u")
seq.add_readout_event("rx", "100u")
rect = RectFunction() seq.add_blank_event("TR", "1m")
seq.set_tx_shape(tx, rect)
blank = Event("blank", "3u", seq)
seq.add_event(blank)
rx = Event("rx", "50u", seq)
#rx.set_rx_phase(0)
seq.set_rx(rx, True)
seq.add_event(rx)
TR = Event("TR", "1m", seq)
seq.add_event(TR)
json = seq.to_json() json = seq.to_json()
print(json) print(json)
sim = Simulator() sim = Simulator()
sim.set_averages(100) sim.set_averages(100)
# Returns the data at the RX event
result = sim.run_sequence(seq) result = sim.run_sequence(seq)
self.assertIsNotNone(result)
self.assertTrue(hasattr(result, "tdx"))
self.assertTrue(hasattr(result, "tdy"))
self.assertGreater(len(result.tdx), 0)
self.assertGreater(len(result.tdy), 0)
# Plotting the result can be useful for visual inspection during development
plt.plot(result.tdx, abs(result.tdy)) plt.plot(result.tdx, abs(result.tdy))
plt.show() plt.show()
def test_simulation_run_sequence(self):
seq = QuackSequence("test - simulation run sequence")
tx = Event("tx", "10u", seq)
seq.add_event(tx)
seq.set_tx_amplitude(tx, 1)
seq.set_tx_phase(tx, 0)
json = seq.to_json()
print(json)
rect = RectFunction()
seq.set_tx_shape(tx, rect)
blank = Event("blank", "3u", seq)
seq.add_event(blank)
rx = Event("rx", "100u", seq)
seq.set_rx(rx, True)
seq.add_event(rx)
TR = Event("TR", "1m", seq)
seq.add_event(TR)
sim = Simulator()
sim.set_averages(100)
result = sim.run_sequence(seq)
self.assertIsNotNone(result)
self.assertTrue(hasattr(result, "tdx"))
self.assertTrue(hasattr(result, "tdy"))
self.assertGreater(len(result.tdx), 0)
self.assertGreater(len(result.tdy), 0)
# Plotting the result can be useful for visual inspection during development
plt.plot(result.tdx, abs(result.tdy))
plt.show()
if __name__ == "__main__":
unittest.main()