mirror of
https://github.com/nqrduck/quackseq-simulator.git
synced 2024-12-22 05:00:24 +00:00
Added phase cycling readout scheme.
This commit is contained in:
parent
0720f19d87
commit
f39af81d68
2 changed files with 47 additions and 20 deletions
|
@ -64,7 +64,7 @@ class SimulatorController(SpectrometerController):
|
||||||
* 1e6
|
* 1e6
|
||||||
)
|
)
|
||||||
|
|
||||||
rx_begin, rx_stop, phase = self.translate_rx_event(sequence)
|
rx_begin, rx_stop, readout_scheme = self.translate_rx_event(sequence)
|
||||||
# If we have a RX event, we need to cut the result to the RX event
|
# If we have a RX event, we need to cut the result to the RX event
|
||||||
if rx_begin and rx_stop:
|
if rx_begin and rx_stop:
|
||||||
evidx = np.where((tdx > rx_begin) & (tdx < rx_stop))[0]
|
evidx = np.where((tdx > rx_begin) & (tdx < rx_stop))[0]
|
||||||
|
@ -85,8 +85,20 @@ class SimulatorController(SpectrometerController):
|
||||||
else:
|
else:
|
||||||
measurement_data.add_dataset(tdx, result / simulation.averages)
|
measurement_data.add_dataset(tdx, result / simulation.averages)
|
||||||
|
|
||||||
if phase:
|
if readout_scheme:
|
||||||
measurement_data.phase_shift(phase, cycle)
|
measurement_data.phase_shift(readout_scheme[cycle][1], cycle)
|
||||||
|
|
||||||
|
|
||||||
|
if readout_scheme and number_phasecycles > 1:
|
||||||
|
# Apply the readout scheme
|
||||||
|
tdy = np.zeros(len(measurement_data.tdx[0]), dtype=complex)
|
||||||
|
for cycle in range(number_phasecycles):
|
||||||
|
tdy += (readout_scheme[cycle][0] * measurement_data.tdy[cycle])
|
||||||
|
|
||||||
|
measurement_data.add_dataset(measurement_data.tdx[0], tdy)
|
||||||
|
|
||||||
|
logger.info(f"Length of tdy: {len(tdy)}")
|
||||||
|
|
||||||
|
|
||||||
return measurement_data
|
return measurement_data
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,14 @@ logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class TestQuackSequence(unittest.TestCase):
|
class TestQuackSequence(unittest.TestCase):
|
||||||
|
|
||||||
def test_event_creation(self):
|
def test_event_creation(self):
|
||||||
seq = QuackSequence("test - event creation")
|
seq = QuackSequence("test - event creation")
|
||||||
seq.add_pulse_event("tx", "10u", 100, 90.0, RectFunction())
|
seq.add_pulse_event("tx", "10u", 100, 90.0, RectFunction())
|
||||||
seq.add_blank_event("blank", "3u")
|
seq.add_blank_event("blank", "3u")
|
||||||
seq.add_readout_event("rx", "100u", phase=90.0)
|
seq.add_readout_event("rx", "100u")
|
||||||
seq.add_blank_event("TR", "1m")
|
seq.add_blank_event("TR", "1m")
|
||||||
|
|
||||||
sim = Simulator()
|
sim = Simulator()
|
||||||
|
@ -32,7 +33,6 @@ class TestQuackSequence(unittest.TestCase):
|
||||||
self.assertGreater(len(result.tdx[0]), 0)
|
self.assertGreater(len(result.tdx[0]), 0)
|
||||||
self.assertGreater(len(result.tdy[0]), 0)
|
self.assertGreater(len(result.tdy[0]), 0)
|
||||||
|
|
||||||
|
|
||||||
logger.info("Plotting imaginary part")
|
logger.info("Plotting imaginary part")
|
||||||
plt.plot(result.tdx[0], result.tdy[0].imag, label="imaginary")
|
plt.plot(result.tdx[0], result.tdy[0].imag, label="imaginary")
|
||||||
logger.info("Plotting real part")
|
logger.info("Plotting real part")
|
||||||
|
@ -72,7 +72,6 @@ class TestQuackSequence(unittest.TestCase):
|
||||||
self.assertGreater(len(result.tdx[0]), 0)
|
self.assertGreater(len(result.tdx[0]), 0)
|
||||||
self.assertGreater(len(result.tdy[0]), 0)
|
self.assertGreater(len(result.tdy[0]), 0)
|
||||||
|
|
||||||
# Plotting the result can be useful for visual inspection during development
|
|
||||||
plt.plot(result.tdx[0], abs(result.tdy[0]))
|
plt.plot(result.tdx[0], abs(result.tdy[0]))
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
|
@ -128,14 +127,14 @@ class TestQuackSequence(unittest.TestCase):
|
||||||
seq.add_event(pi_half)
|
seq.add_event(pi_half)
|
||||||
seq.set_tx_amplitude(pi_half, 100)
|
seq.set_tx_amplitude(pi_half, 100)
|
||||||
seq.set_tx_phase(pi_half, 0)
|
seq.set_tx_phase(pi_half, 0)
|
||||||
seq.set_tx_n_phase_cycles(pi_half, 4) # 0 90 180 270
|
seq.set_tx_n_phase_cycles(pi_half, 4) # 0 90 180 270
|
||||||
seq.set_tx_phase_cycle_group(pi_half, 0)
|
seq.set_tx_phase_cycle_group(pi_half, 0)
|
||||||
|
|
||||||
# Wait for TE/2 (approx)
|
# Wait for TE/2 (approx)
|
||||||
seq.add_blank_event("te/2", "150u")
|
seq.add_blank_event("te/2", "150u")
|
||||||
|
|
||||||
# Create the 180 degree pulse
|
# Create the 180 degree pulse
|
||||||
pi = Event("pi", "12u", seq)
|
pi = Event("pi", "12u", seq)
|
||||||
seq.add_event(pi)
|
seq.add_event(pi)
|
||||||
seq.set_tx_amplitude(pi, 100)
|
seq.set_tx_amplitude(pi, 100)
|
||||||
seq.set_tx_phase(pi, 180)
|
seq.set_tx_phase(pi, 180)
|
||||||
|
@ -145,15 +144,9 @@ class TestQuackSequence(unittest.TestCase):
|
||||||
# Wait another blanking time
|
# Wait another blanking time
|
||||||
seq.add_blank_event("blank", "100u")
|
seq.add_blank_event("blank", "100u")
|
||||||
|
|
||||||
# Create phase table
|
|
||||||
phase_table = PhaseTable(seq)
|
|
||||||
|
|
||||||
# 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
|
|
||||||
readout_scheme = [(1,0), (1, 270), (1, 180), (1, 90)]
|
|
||||||
|
|
||||||
phase_table.rx_phase_sign = readout_scheme
|
|
||||||
|
|
||||||
result = Simulator().run_sequence(seq)
|
result = Simulator().run_sequence(seq)
|
||||||
|
|
||||||
|
# Plotting the results
|
||||||
plt.title("Phase cycling")
|
plt.title("Phase cycling")
|
||||||
logger.info(f"Number of data sets {len(result.tdy)}")
|
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[0], result.tdy[0].real, label="pc 1")
|
||||||
|
@ -162,8 +155,30 @@ class TestQuackSequence(unittest.TestCase):
|
||||||
plt.plot(result.tdx[3], result.tdy[3].real, label="pc 4")
|
plt.plot(result.tdx[3], result.tdy[3].real, label="pc 4")
|
||||||
plt.legend()
|
plt.legend()
|
||||||
plt.show()
|
plt.show()
|
||||||
# rx = Event("rx", "100u", seq)
|
|
||||||
|
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
|
||||||
|
readout_scheme = [[1, 0], [1, 270], [1, 180], [1, 90]]
|
||||||
|
|
||||||
|
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)}")
|
||||||
|
plt.plot(result.tdx[0], abs(result.tdy[0]), label="pc 1")
|
||||||
|
plt.plot(result.tdx[1], abs(result.tdy[1]), label="pc 2")
|
||||||
|
plt.plot(result.tdx[2], abs(result.tdy[2]), label="pc 3")
|
||||||
|
plt.plot(result.tdx[3], abs(result.tdy[3]), label="pc 4")
|
||||||
|
plt.plot(result.tdx[4], abs(result.tdy[4]), label="Phase Cycling")
|
||||||
|
plt.legend()
|
||||||
|
plt.show()
|
||||||
# seq.add_event(rx)
|
# seq.add_event(rx)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in a new issue