2024-05-29 06:36:34 +00:00
|
|
|
import unittest
|
|
|
|
import logging
|
|
|
|
import matplotlib.pyplot as plt
|
2024-06-06 17:45:40 +00:00
|
|
|
from quackseq.phase_table import PhaseTable
|
2024-05-29 06:36:34 +00:00
|
|
|
from quackseq.pulsesequence import QuackSequence
|
|
|
|
from quackseq.event import Event
|
|
|
|
from quackseq.functions import RectFunction
|
|
|
|
from quackseq_simulator.simulator import Simulator
|
|
|
|
|
2024-06-06 17:45:40 +00:00
|
|
|
logging.basicConfig(level=logging.INFO)
|
2024-05-29 06:36:34 +00:00
|
|
|
|
2024-06-06 17:45:40 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
2024-05-29 06:36:34 +00:00
|
|
|
|
2024-06-07 15:30:28 +00:00
|
|
|
|
2024-05-29 06:36:34 +00:00
|
|
|
class TestQuackSequence(unittest.TestCase):
|
|
|
|
|
|
|
|
def test_event_creation(self):
|
|
|
|
seq = QuackSequence("test - event creation")
|
2024-06-04 13:34:14 +00:00
|
|
|
seq.add_pulse_event("tx", "10u", 100, 90.0, RectFunction())
|
2024-05-29 06:36:34 +00:00
|
|
|
seq.add_blank_event("blank", "3u")
|
2024-06-07 15:30:28 +00:00
|
|
|
seq.add_readout_event("rx", "100u")
|
2024-05-29 06:36:34 +00:00
|
|
|
seq.add_blank_event("TR", "1m")
|
|
|
|
|
|
|
|
sim = Simulator()
|
|
|
|
sim.set_averages(100)
|
|
|
|
|
2024-05-29 08:22:08 +00:00
|
|
|
sim.settings.noise = 0
|
|
|
|
|
2024-05-29 06:36:34 +00:00
|
|
|
result = sim.run_sequence(seq)
|
|
|
|
self.assertIsNotNone(result)
|
|
|
|
self.assertTrue(hasattr(result, "tdx"))
|
|
|
|
self.assertTrue(hasattr(result, "tdy"))
|
2024-06-07 13:55:37 +00:00
|
|
|
self.assertGreater(len(result.tdx[0]), 0)
|
|
|
|
self.assertGreater(len(result.tdy[0]), 0)
|
2024-05-29 06:36:34 +00:00
|
|
|
|
2024-06-07 13:55:37 +00:00
|
|
|
logger.info("Plotting imaginary part")
|
|
|
|
plt.plot(result.tdx[0], result.tdy[0].imag, label="imaginary")
|
|
|
|
logger.info("Plotting real part")
|
|
|
|
plt.plot(result.tdx[0], result.tdy[0].real, label="real")
|
|
|
|
plt.plot(result.tdx[0], abs(result.tdy[0]), label="abs")
|
2024-06-04 13:34:14 +00:00
|
|
|
plt.legend()
|
2024-05-29 06:36:34 +00:00
|
|
|
plt.show()
|
|
|
|
|
|
|
|
def test_simulation_run_sequence(self):
|
|
|
|
seq = QuackSequence("test - simulation run sequence")
|
|
|
|
|
|
|
|
tx = Event("tx", "10u", seq)
|
|
|
|
seq.add_event(tx)
|
2024-06-03 17:44:27 +00:00
|
|
|
seq.set_tx_amplitude(tx, 100)
|
2024-05-29 06:36:34 +00:00
|
|
|
seq.set_tx_phase(tx, 0)
|
|
|
|
|
|
|
|
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"))
|
2024-06-07 13:55:37 +00:00
|
|
|
self.assertGreater(len(result.tdx[0]), 0)
|
|
|
|
self.assertGreater(len(result.tdy[0]), 0)
|
2024-05-29 06:36:34 +00:00
|
|
|
|
2024-06-07 13:55:37 +00:00
|
|
|
plt.plot(result.tdx[0], abs(result.tdy[0]))
|
2024-05-29 06:36:34 +00:00
|
|
|
plt.show()
|
|
|
|
|
2024-06-07 12:52:15 +00:00
|
|
|
def test_phase_array_generation(self):
|
|
|
|
seq = QuackSequence("test - phase array generation")
|
2024-06-06 17:45:40 +00:00
|
|
|
|
|
|
|
tx = Event("tx", "10u", seq)
|
|
|
|
seq.add_event(tx)
|
|
|
|
seq.set_tx_amplitude(tx, 100)
|
|
|
|
seq.set_tx_phase(tx, 0)
|
|
|
|
seq.set_tx_n_phase_cycles(tx, 2)
|
|
|
|
seq.set_tx_phase_cycle_group(tx, 0)
|
|
|
|
|
|
|
|
rect = RectFunction()
|
|
|
|
seq.set_tx_shape(tx, rect)
|
|
|
|
|
|
|
|
tx2 = Event("tx2", "10u", seq)
|
|
|
|
seq.add_event(tx2)
|
|
|
|
seq.set_tx_amplitude(tx2, 100)
|
|
|
|
seq.set_tx_phase(tx2, 1)
|
2024-06-07 14:48:45 +00:00
|
|
|
seq.set_tx_n_phase_cycles(tx2, 2)
|
2024-06-06 17:45:40 +00:00
|
|
|
seq.set_tx_phase_cycle_group(tx2, 1)
|
|
|
|
|
|
|
|
tx3 = Event("tx3", "10u", seq)
|
|
|
|
seq.add_event(tx3)
|
|
|
|
seq.set_tx_amplitude(tx3, 100)
|
|
|
|
seq.set_tx_phase(tx3, 2)
|
2024-06-07 14:48:45 +00:00
|
|
|
seq.set_tx_n_phase_cycles(tx3, 2)
|
2024-06-07 12:52:15 +00:00
|
|
|
seq.set_tx_phase_cycle_group(tx3, 3)
|
2024-06-06 17:45:40 +00:00
|
|
|
|
|
|
|
sim = Simulator()
|
|
|
|
sim.set_averages(100)
|
|
|
|
|
|
|
|
result = sim.run_sequence(seq)
|
|
|
|
|
2024-06-07 13:55:37 +00:00
|
|
|
plt.plot(result.tdx[0], abs(result.tdy[0]))
|
2024-06-07 14:48:45 +00:00
|
|
|
plt.plot(result.tdx[1], abs(result.tdy[1]))
|
2024-06-06 17:45:40 +00:00
|
|
|
plt.show()
|
|
|
|
|
|
|
|
phase_table = PhaseTable(seq)
|
2024-05-29 06:36:34 +00:00
|
|
|
|
2024-06-07 12:52:15 +00:00
|
|
|
logger.info(phase_table.n_phase_cycles)
|
2024-06-07 14:48:45 +00:00
|
|
|
self.assertEqual(phase_table.n_phase_cycles, 8)
|
2024-06-07 12:52:15 +00:00
|
|
|
self.assertEqual(phase_table.n_parameters, 3)
|
|
|
|
|
|
|
|
def test_phase_cycling(self):
|
|
|
|
|
|
|
|
seq = QuackSequence("test - phase cycling")
|
|
|
|
|
2024-06-07 15:30:28 +00:00
|
|
|
# Simple spin echo sequence with phase cycling.
|
2024-06-07 12:52:15 +00:00
|
|
|
# Create the first 90 degree pulse
|
|
|
|
pi_half = Event("pi_half", "6u", seq)
|
|
|
|
seq.add_event(pi_half)
|
|
|
|
seq.set_tx_amplitude(pi_half, 100)
|
|
|
|
seq.set_tx_phase(pi_half, 0)
|
2024-06-07 15:30:28 +00:00
|
|
|
seq.set_tx_n_phase_cycles(pi_half, 4) # 0 90 180 270
|
|
|
|
seq.set_tx_phase_cycle_group(pi_half, 0)
|
2024-06-07 12:52:15 +00:00
|
|
|
|
|
|
|
# Wait for TE/2 (approx)
|
|
|
|
seq.add_blank_event("te/2", "150u")
|
|
|
|
|
|
|
|
# Create the 180 degree pulse
|
2024-06-07 15:30:28 +00:00
|
|
|
pi = Event("pi", "12u", seq)
|
2024-06-07 12:52:15 +00:00
|
|
|
seq.add_event(pi)
|
|
|
|
seq.set_tx_amplitude(pi, 100)
|
2024-06-08 12:18:52 +00:00
|
|
|
seq.set_tx_phase(pi, 90)
|
2024-06-07 12:52:15 +00:00
|
|
|
seq.set_tx_n_phase_cycles(pi, 1)
|
|
|
|
seq.set_tx_phase_cycle_group(pi, 0)
|
|
|
|
|
|
|
|
# Wait another blanking time
|
|
|
|
seq.add_blank_event("blank", "100u")
|
|
|
|
|
|
|
|
result = Simulator().run_sequence(seq)
|
2024-06-07 15:30:28 +00:00
|
|
|
|
|
|
|
# Plotting the results
|
2024-06-07 12:52:15 +00:00
|
|
|
plt.title("Phase cycling")
|
2024-06-07 14:48:45 +00:00
|
|
|
logger.info(f"Number of data sets {len(result.tdy)}")
|
|
|
|
plt.plot(result.tdx[0], result.tdy[0].real, label="pc 1")
|
|
|
|
plt.plot(result.tdx[1], result.tdy[1].real, label="pc 2")
|
|
|
|
plt.plot(result.tdx[2], result.tdy[2].real, label="pc 3")
|
|
|
|
plt.plot(result.tdx[3], result.tdy[3].real, label="pc 4")
|
2024-06-07 12:52:15 +00:00
|
|
|
plt.legend()
|
|
|
|
plt.show()
|
2024-06-07 15:30:28 +00:00
|
|
|
|
|
|
|
rx = Event("rx", "100u", seq)
|
|
|
|
seq.add_event(rx)
|
|
|
|
seq.set_rx(rx, True)
|
|
|
|
|
|
|
|
# Readout scheme for phase cycling TX pulses have the scheme 0 90 180 270 for the first pulse and 180 always for the second pulse
|
2024-06-08 12:18:52 +00:00
|
|
|
readout_scheme = [[1, 0], [1, 90], [1, 180], [1, 270]]
|
2024-06-07 15:30:28 +00:00
|
|
|
|
|
|
|
seq.set_rx_readout_scheme(rx, readout_scheme)
|
|
|
|
|
|
|
|
result = Simulator().run_sequence(seq)
|
|
|
|
|
|
|
|
# Plotting the results
|
|
|
|
plt.title("Phase cycling")
|
|
|
|
logger.info(f"Number of data sets {len(result.tdy)}")
|
2024-06-16 16:22:02 +00:00
|
|
|
plt.plot(result.tdx[0], result.tdy[0].real, label="pc 1 real")
|
|
|
|
plt.plot(result.tdx[0], result.tdy[0].imag, label="pc 2 imag")
|
|
|
|
plt.legend()
|
|
|
|
plt.show()
|
2024-06-08 12:18:52 +00:00
|
|
|
plt.plot(result.tdx[1], result.tdy[1].real, label="pc 2")
|
2024-06-16 16:22:02 +00:00
|
|
|
plt.plot(result.tdx[1], result.tdy[1].imag, label="pc 2")
|
|
|
|
plt.legend()
|
|
|
|
plt.show()
|
2024-06-08 12:18:52 +00:00
|
|
|
plt.plot(result.tdx[2], result.tdy[2].real, label="pc 3")
|
2024-06-16 16:22:02 +00:00
|
|
|
plt.plot(result.tdx[2], result.tdy[2].imag, label="pc 3")
|
|
|
|
plt.legend()
|
|
|
|
plt.show()
|
2024-06-08 12:18:52 +00:00
|
|
|
plt.plot(result.tdx[3], result.tdy[3].real, label="pc 4")
|
2024-06-16 16:22:02 +00:00
|
|
|
plt.plot(result.tdx[3], result.tdy[3].imag, label="pc 4")
|
|
|
|
plt.legend()
|
|
|
|
plt.show()
|
2024-06-07 15:30:28 +00:00
|
|
|
plt.plot(result.tdx[4], abs(result.tdy[4]), label="Phase Cycling")
|
|
|
|
plt.legend()
|
|
|
|
plt.show()
|
2024-06-07 12:52:15 +00:00
|
|
|
# seq.add_event(rx)
|
2024-06-07 15:30:28 +00:00
|
|
|
|
|
|
|
|
2024-05-29 06:36:34 +00:00
|
|
|
if __name__ == "__main__":
|
|
|
|
unittest.main()
|