# Single shot readout Using {mod}`.pulsed` mode and template matching we can demodulate and integrate the resonator response based on the qubit state without averaging. This means we get a single point in the IQ-plane for each measurement perfomed. We interleave preparing qubit in the ground state (no $\pi$ pulse) and preparing qubit in the excited state ($\sin^2$ envelope $\pi$ pulse) followed by a readout pulse (square pulse) and we perfom this measurement `nr_averages` times. We get two blobs each representing qubit in either ground or excited state. ![Single shot readout pulse sequence](images/single_shot_readout_pulse_sequence.svg){align=center} The full source code for this experiment is available at [presto-measure/single_shot_readout.py][single_shot_readout.py]. Here, we first run the single shot readout experiment and analyze the data, and then we have a more detailed look at the most important parts of the code. You can create a new experiment and run it on your Presto. Be sure to change the parameters of `SingleShotReadout` to match your experiment and change `presto_address` to match the IP address of your Presto: ```python from single_shot_readout import SingleShotReadout import numpy as np experiment = SingleShotReadout( readout_freq=7.81438e9, control_freq=5.5229793e9, readout_amp=0.08, control_amp=0.176, readout_duration=1000e-9, control_duration=50e-9, readout_sample_delay=0e-9, sample_duration=2500e-9, readout_port=1, control_port=4, sample_port=1, wait_delay=400e-6, template_match_start=268e-9, template_match_duration=800e-9, template_match_phase=0.0, num_averages=5000, ) presto_address = "192.168.88.65" # your Presto IP address save_filename = experiment.run(presto_address) ``` Or you can also load older data: ```python experiment = SingleShotReadout.load("../data/single_shot_readout_20230622_145840.h5") ``` In either case, we analyze the data to get a nice plot: ```python experiment.analyze(rotate_optimally=False) ``` ```{image} images/single_shot_readout_not_rotated_light.svg :align: center :class: only-light ``` ```{image} images/single_shot_readout_not_rotated_dark.svg :align: center :class: only-dark ``` Each point represents one demodulated and integrated measurement (blue/orange markers for the qubit in the ground/excited state). --- Measured points can be rotated in post-processing so that all the information is contained in only I-quadrature. The angle of rotation can be used to set the `template_match_phase` so that the templates are rotated in the IQ-plane such that all the information is contained in one quardature. ```python experiment.analyze(rotate_optimally=True) ``` ```{image} images/single_shot_readout_light.svg :align: center :class: only-light ``` ```{image} images/single_shot_readout_dark.svg :align: center :class: only-dark ``` ## Code explanation Here we discuss the main parts of the code in [presto-measure/single_shot_readout.py][single_shot_readout.py]. :::{note} If this is your first measurement in {mod}`.pulsed` mode, you might want to first have a look at the [Rabi amplitude](rabi_amp) chapter in this tutorial. There we describe the code more pedagogically and in more detail. ::: We program two amplitudes in the scale_lut. Zero amplitude to keep the qubit in the ground state and `self.control_amp` to apply a $\pi$ pulse. ```python pls.setup_scale_lut(self.control_port, group=0, scales=[0, self.control_amp]) ``` --- We then set the matching templates similarly to setting any other templates. They will be multiplied element vise with the demodulated sampled data and the result will be summed. In this example, we choose the simplest template, the square of `template_match_duration` duration. We set the matching templates in pairs. So we use `template1` to integrate the I-quadrature and `template2` to integrate the Q-quadrature. ```python shape = np.ones(int(round(self.template_match_duration * pls.get_fs("dac")))) match_events = pls.setup_template_matching_pair( input_port=self.sample_port, template1=shape * np.exp(self.template_match_phase), template2=1j * shape * np.exp(self.template_match_phase), ) ``` The `template_match_phase` determines the angle of the IQ coordinate system allowing us to rotate the readout data. --- The core of the measurement is the definition of the experimental sequence: ```python for i in range(2): pls.select_scale(T, i, self.control_port, group=0) pls.output_pulse(T, [control_pulse]) T += self.control_duration pls.output_pulse(T, [readout_pulse]) pls.store(T + self.readout_sample_delay) pls.match(T + self.template_match_start, [match_events]) T += self.readout_duration + self.wait_delay ``` We use a `for` loop to either select zero amplitude or the amplitude of the $\pi$ pulse and output the `control_pulse`. As usual, the resonator-readout pulse and the data acquisition are scheduled right after the control pulse. The matching has to be scheduled within a `store` window, and finally we wait for the qubit to decay back to the ground state. --- To finally execute the measurement, we call {meth}`~.Pulsed.run`: ```python pls.run(period=T, repeat_count=1, num_averages=self.num_averages) self.t_arr, self.store_arr = pls.get_store_data() self.match_arr = pls.get_template_matching_data([match_events]) ``` Appart from the usual averaged `store_arr` result, we obtain the `match_arr` by calling {meth}`~.Pulsed.get_template_matching_data`. `len(match_arr)` is the same as the number of matching templates. This is two in our example, as we are setup one `template_matching_pair`. `match_arr[0]` contains the outcomes of matching with `template1` (I-quadrature) in chronological order. Similarly, `match_arr[1]` contains the outcomes of matching with `template2` (Q-quadrature). We performed 5000 averages, meaning 10000 measurements in total (5000 ground and 5000 excited qubit state measurements). These measurements are interleaved and so are the template matching results. ```python complex_match_data = self.match_arr[0] + 1j * self.match_arr[1] ground_data = complex_match_data[::2] excited_data = complex_match_data[1::2] ``` So we simply pick out every other element of the array to separate the `ground_data` from the `excited_data`. [single_shot_readout.py]: https://github.com/intermod-pro/presto-measure/blob/master/single_shot_readout.py