Exemple #1
0
    def analyze(self, all_plots: bool = False):
        if self.t_arr is None:
            raise RuntimeError
        if self.store_arr is None:
            raise RuntimeError

        import matplotlib.pyplot as plt

        ret_fig = []

        idx = np.arange(IDX_LOW, IDX_HIGH)
        t_low = self.t_arr[IDX_LOW]
        t_high = self.t_arr[IDX_HIGH]

        if all_plots:
            # Plot raw store data for first iteration as a check
            fig1, ax1 = plt.subplots(2, 1, sharex=True, tight_layout=True)
            ax11, ax12 = ax1
            ax11.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax12.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax11.plot(1e9 * self.t_arr, np.abs(self.store_arr[0, 0, :]))
            ax12.plot(1e9 * self.t_arr, np.angle(self.store_arr[0, 0, :]))
            ax12.set_xlabel("Time [ns]")
            fig1.show()
            ret_fig.append(fig1)

        # Analyze T1
        resp_arr = np.mean(self.store_arr[:, 0, idx], axis=-1)
        resp_arr = rotate_opt(resp_arr)

        # Fit data
        popt, perr = _fit_simple(self.delay_arr, np.real(resp_arr))

        T1 = popt[0]
        T1_err = perr[0]
        print("T1 time I: {} +- {} us".format(1e6 * T1, 1e6 * T1_err))

        if all_plots:
            fig2, ax2 = plt.subplots(4,
                                     1,
                                     sharex=True,
                                     figsize=(6.4, 6.4),
                                     tight_layout=True)
            ax21, ax22, ax23, ax24 = ax2
            ax21.plot(1e6 * self.delay_arr, np.abs(resp_arr))
            ax22.plot(1e6 * self.delay_arr, np.unwrap(np.angle(resp_arr)))
            ax23.plot(1e6 * self.delay_arr, np.real(resp_arr))
            ax23.plot(1e6 * self.delay_arr, _decay(self.delay_arr, *popt),
                      '--')
            ax24.plot(1e6 * self.delay_arr, np.imag(resp_arr))

            ax21.set_ylabel("Amplitude [FS]")
            ax22.set_ylabel("Phase [rad]")
            ax23.set_ylabel("I [FS]")
            ax24.set_ylabel("Q [FS]")
            ax2[-1].set_xlabel("Control-readout delay [μs]")
            fig2.show()
            ret_fig.append(fig2)

        # bigger plot just for I quadrature
        data_max = np.abs(resp_arr.real).max()
        unit = ""
        mult = 1.0
        if data_max < 1e-6:
            unit = "n"
            mult = 1e9
        elif data_max < 1e-3:
            unit = "μ"
            mult = 1e6
        elif data_max < 1e0:
            unit = "m"
            mult = 1e3

        fig3, ax3 = plt.subplots(tight_layout=True)
        ax3.plot(1e6 * self.delay_arr, mult * np.real(resp_arr), '.')
        ax3.plot(1e6 * self.delay_arr, mult * _decay(self.delay_arr, *popt),
                 '--')
        ax3.set_ylabel(f"I quadrature [{unit:s}FS]")
        ax3.set_xlabel(r"Control-readout delay [μs]")
        ax3.set_title("T1 = {:s} μs".format(
            format_precision(1e6 * T1, 1e6 * T1_err)))
        fig3.show()
        ret_fig.append(fig3)

        return ret_fig
def load(load_filename):
    with h5py.File(load_filename, "r") as h5f:
        num_averages = h5f.attrs["num_averages"]
        control_freq = h5f.attrs["control_freq"]
        readout_freq = h5f.attrs["readout_freq"]
        readout_duration = h5f.attrs["readout_duration"]
        readout_amp = h5f.attrs["readout_amp"]
        control_amp = h5f.attrs["control_amp"]
        sample_duration = h5f.attrs["sample_duration"]
        rabi_n = h5f.attrs["rabi_n"]
        rabi_dt = h5f.attrs["rabi_dt"]
        wait_delay = h5f.attrs["wait_delay"]
        readout_sample_delay = h5f.attrs["readout_sample_delay"]
        t_arr = h5f["t_arr"][()]
        store_arr = h5f["store_arr"][()]
        source_code = h5f["source_code"][()]

    t_low = 1500 * 1e-9
    t_high = 2000 * 1e-9
    t_span = t_high - t_low
    idx_low = np.argmin(np.abs(t_arr - t_low))
    idx_high = np.argmin(np.abs(t_arr - t_high))
    idx = np.arange(idx_low, idx_high)
    nr_samples = len(idx)
    dt = t_arr[1] - t_arr[0]
    f_arr = np.fft.rfftfreq(len(t_arr[idx]), dt)

    fig1, ax1 = plt.subplots(2, 1, sharex=True, tight_layout=True)
    ax11, ax12 = ax1
    ax11.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    ax12.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    ax11.plot(1e9 * t_arr, np.abs(store_arr[0, 0, :]))
    ax12.plot(1e9 * t_arr, np.angle(store_arr[0, 0, :]))
    ax12.set_xlabel("Time [ns]")
    fig1.show()

    # Analyze Rabi
    resp_arr = np.mean(store_arr[:, 0, idx], axis=-1)
    data = rotate_opt(resp_arr)
    len_arr = rabi_dt * np.arange(rabi_n)

    # Fit data
    # popt_a, perr_a = fit_period(len_arr, np.abs(data))
    # popt_p, perr_p = fit_period(len_arr, np.angle(data))
    popt_x, perr_x = fit_period(len_arr, np.real(data))
    # popt_y, perr_y = fit_period(len_arr, np.imag(data))

    period = popt_x[3]
    period_err = perr_x[3]
    pi_len = round(period / 2 / 2e-9) * 2e-9
    pi_2_len = round(period / 4 / 2e-9) * 2e-9
    print("Rabi period: {} +- {} ns".format(1e9 * period, 1e9 * period_err))
    print("Pi pulse length: {:.0f} ns".format(1e9 * pi_len))
    print("Pi/2 pulse length: {:.0f} ns".format(1e9 * pi_2_len))
    print(f"decay: {popt_x[2]} s")

    fig2, ax2 = plt.subplots(4, 1, sharex=True, figsize=(6.4, 6.4), tight_layout=True)
    ax21, ax22, ax23, ax24 = ax2
    ax21.plot(1e9 * len_arr, np.abs(data))
    # ax21.plot(1e9 * len_arr, func(len_arr, *popt_a), '--')
    ax22.plot(1e9 * len_arr, np.angle(data))
    # ax22.plot(1e9 * len_arr, func(len_arr, *popt_p), '--')
    ax23.plot(1e9 * len_arr, np.real(data))
    ax23.plot(1e9 * len_arr, func(len_arr, *popt_x), '--')
    ax24.plot(1e9 * len_arr, np.imag(data))
    # ax24.plot(1e9 * len_arr, func(len_arr, *popt_y), '--')

    ax21.set_ylabel("Amplitude [FS]")
    ax22.set_ylabel("Phase [rad]")
    ax23.set_ylabel("I [FS]")
    ax24.set_ylabel("Q [FS]")
    ax2[-1].set_xlabel("Pulse length [ns]")
    fig2.show()

    mult, unit = scale_unit(data.real)
    mult_t, unit_t = scale_unit(len_arr)

    fig3, ax3 = plt.subplots(tight_layout=True)
    ax3.plot(mult_t * len_arr, mult * np.real(data), '.')
    ax3.plot(mult_t * len_arr, mult * func(len_arr, *popt_x), '--')
    ax3.set_xlabel(f"Pulse length [{unit_t:s}s]")
    ax3.set_ylabel(f"I quadrature [{unit:s}FS]")
    fig3.show()

    return fig1, fig2, fig3
    def analyze(self, crazy=False, blit=True):
        if self.t_arr is None:
            raise RuntimeError
        if self.store_arr is None:
            raise RuntimeError

        import matplotlib.pyplot as plt
        from presto.utils import rotate_opt

        ret_fig = []

        t_low = 1500 * 1e-9
        t_high = 2000 * 1e-9
        # t_span = t_high - t_low
        idx_low = np.argmin(np.abs(self.t_arr - t_low))
        idx_high = np.argmin(np.abs(self.t_arr - t_high))
        idx = np.arange(idx_low, idx_high)
        # nr_samples = len(idx)

        # Analyze
        resp_arr = np.mean(self.store_arr[:, 0, idx], axis=-1)
        data = rotate_opt(resp_arr).real

        nr_delays = len(self.ramsey_delay_arr)
        nr_amps = len(self.first_pulse_amp_arr)
        data.shape = (nr_amps, nr_delays)
        self._amp_idx = 0

        data_max = np.abs(data).max()
        unit = ""
        mult = 1.0
        if data_max < 1e-6:
            unit = "n"
            mult = 1e9
        elif data_max < 1e-3:
            unit = "μ"
            mult = 1e6
        elif data_max < 1e0:
            unit = "m"
            mult = 1e3

        if np.mean(data) < 0:
            data *= -mult
        else:
            data *= mult
        data_max = np.max(data)
        data_min = np.min(data)
        data_rng = data_max - data_min

        # choose limits for colorbar
        cutoff = 0.0  # %
        lowlim = np.percentile(data, cutoff)
        highlim = np.percentile(data, 100. - cutoff)

        x_data = 1e9 * self.ramsey_delay_arr
        y_data = self.first_pulse_amp_arr**2 * 100

        # extent
        x_min = x_data[0]
        x_max = x_data[-1]
        x_rng = x_max - x_min
        dx = x_data[1] - x_data[0]
        y_min = y_data[0]
        y_max = y_data[-1]
        dy = y_data[1] - y_data[0]

        fig1 = plt.figure(tight_layout=True, figsize=(12.8, 4.8))
        ax11 = fig1.add_subplot(1, 2, 1)
        im = ax11.imshow(
            data,
            origin='lower',
            aspect='auto',
            interpolation='none',
            extent=(x_min - dx / 2, x_max + dx / 2, y_min - dy / 2, y_max + dy / 2),
            vmin=lowlim,
            vmax=highlim,
        )
        self._line_sel = ax11.axhline(y_data[self._amp_idx], ls="--", c="k", lw=3, animated=blit)
        ax11.set_xlabel("Ramsey delay [ns]")
        ax11.set_ylabel("First pulse power [%]")
        cb = fig1.colorbar(im)
        # cb.set_label(f"Response I quadrature [{unit:s}FS]")
        ax11.set_title(f"Response I quadrature [{unit:s}FS]")

        ax12 = fig1.add_subplot(1, 2, 2)
        ax12.yaxis.set_label_position("right")
        ax12.yaxis.tick_right()
        self._line_slice, = ax12.plot(x_data, data[self._amp_idx], '.', label="measured", animated=blit)
        try:
            if crazy:
                popt, _ = _fit_simple(x_data, data[self._amp_idx])
                fit_data = _func(x_data, *popt)
            else:
                popt, _ = _fit_simple(x_data, data[self._amp_idx])
                fit_data = _func(x_data, *popt)
            self._line_fit, = ax12.plot(x_data, fit_data, '--', label="fit", animated=blit)
        except Exception:
            self._line_fit, = ax12.plot(x_data, np.full_like(x_data, np.nan), '--', label="fit", animated=blit)
        ax12.set_xlim(x_min - 0.05 * x_rng, x_max + 0.05 * x_rng)
        ax12.set_ylim(data_min - 0.05 * data_rng, data_max + 0.05 * data_rng)
        ax12.set_xlabel("Ramsey delay [ns]")
        ax12.set_title(f"Response I quadrature [{unit:s}FS]")
        ax12.legend(loc="lower right", ncol=2)

        def onbuttonpress(event):
            if event.inaxes == ax11:
                self._amp_idx = np.argmin(np.abs(y_data - event.ydata))
                update()

        def onkeypress(event):
            if event.inaxes == ax11:
                if event.key == "up":
                    self._amp_idx += 1
                    if self._amp_idx >= nr_amps:
                        self._amp_idx = nr_amps - 1
                    update()
                elif event.key == "down":
                    self._amp_idx -= 1
                    if self._amp_idx < 0:
                        self._amp_idx = 0
                    update()

        def update():
            self._line_sel.set_ydata([y_data[self._amp_idx], y_data[self._amp_idx]])
            # ax1.set_title(f"amp = {amp_arr[AMP_IDX]:.2e}")
            # print(f"drive amp {self._amp_idx:d}: {qubit_amp_arr[self._amp_idx]:.2e} FS = {amp_dBFS[self._amp_idx]:.1f} dBFS")
            self._line_slice.set_ydata(data[self._amp_idx])
            try:
                if crazy:
                    popt, _ = _fit_simple(x_data, data[self._amp_idx])
                    fit_data = _func(x_data, *popt)
                else:
                    popt, _ = _fit_simple(x_data, data[self._amp_idx])
                    fit_data = _func(x_data, *popt)
                self._line_fit.set_ydata(fit_data)
            except Exception:
                self._line_fit.set_ydata(np.full_like(x_data, np.nan))
            # ax2.set_title("")
            if blit:
                fig1.canvas.restore_region(self._bg)
                ax11.draw_artist(self._line_sel)
                ax12.draw_artist(self._line_slice)
                ax12.draw_artist(self._line_fit)
                fig1.canvas.blit(fig1.bbox)
                # fig1.canvas.flush_events()
            else:
                fig1.canvas.draw()

        fig1.canvas.mpl_connect('button_press_event', onbuttonpress)
        fig1.canvas.mpl_connect('key_press_event', onkeypress)

        fig1.show()
        if blit:
            fig1.canvas.draw()
            # fig1.canvas.flush_events()
            self._bg = fig1.canvas.copy_from_bbox(fig1.bbox)
            ax11.draw_artist(self._line_sel)
            ax12.draw_artist(self._line_slice)
            ax12.draw_artist(self._line_fit)
            fig1.canvas.blit(fig1.bbox)

        ret_fig.append(fig1)

        # Fit the lowest powers
        idx_fit = np.s_[0:75]
        pwr_fit = y_data[idx_fit]
        n_fit = np.zeros_like(pwr_fit)
        for ii, fit_data in enumerate(data[idx_fit]):
            try:
                popt, _ = _fit_simple(x_data, fit_data)
                n_fit[ii] = popt[0]
            except Exception:
                n_fit[ii] = np.nan
        fig2, ax2 = plt.subplots(tight_layout=True)
        ax2.plot(pwr_fit, n_fit, '.')
        ax2.grid()
        ax2.set_xlabel("First pulse power [%]")
        ax2.set_ylabel("Fitted number of photons")
        fig2.show()
        ret_fig.append(fig2)

        return ret_fig
def load(load_filename):
    with h5py.File(load_filename, "r") as h5f:
        num_averages = h5f.attrs["num_averages"]
        control_freq_1 = h5f.attrs["control_freq_1"]
        control_freq_2 = h5f.attrs["control_freq_2"]
        control_if = h5f.attrs["control_if"]
        readout_freq_1 = h5f.attrs["readout_freq_1"]
        readout_freq_2 = h5f.attrs["readout_freq_2"]
        readout_duration = h5f.attrs["readout_duration"]
        control_duration = h5f.attrs["control_duration"]
        readout_amp = h5f.attrs["readout_amp"]
        control_amp_1 = h5f.attrs["control_amp_1"]
        control_amp_2 = h5f.attrs["control_amp_2"]
        sample_duration = h5f.attrs["sample_duration"]
        wait_delay = h5f.attrs["wait_delay"]
        readout_sample_delay = h5f.attrs["readout_sample_delay"]
        coupler_dc_bias = h5f.attrs["coupler_dc_bias"]
        coupler_ac_amp = h5f.attrs["coupler_ac_amp"]
        nr_freqs = h5f.attrs["nr_freqs"]
        coupler_ac_duration = h5f.attrs["coupler_ac_duration"]
        t_arr = h5f["t_arr"][()]
        store_arr = h5f["store_arr"][()]
        coupler_ac_freq_arr = h5f["coupler_ac_freq_arr"][()]

    t_low = 1500 * 1e-9
    t_high = 2000 * 1e-9
    idx_low = np.argmin(np.abs(t_arr - t_low))
    idx_high = np.argmin(np.abs(t_arr - t_high))
    idx = np.arange(idx_low, idx_high)

    # Plot raw store data for first iteration as a check
    fig1, ax1 = plt.subplots(2, 1, sharex=True, tight_layout=True)
    ax11, ax12 = ax1
    ax11.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    ax12.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    ax11.plot(1e9 * t_arr, np.abs(store_arr[0, 0, :]))
    ax12.plot(1e9 * t_arr, np.angle(store_arr[0, 0, :]))
    ax12.set_xlabel("Time [ns]")
    fig1.show()

    # Analyze T2
    resp_arr = np.mean(store_arr[:, 0, idx], axis=-1)
    data = rotate_opt(resp_arr)

    fig2, ax2 = plt.subplots(4,
                             1,
                             sharex=True,
                             figsize=(6.4, 6.4),
                             tight_layout=True)
    ax21, ax22, ax23, ax24 = ax2
    ax21.plot(coupler_ac_freq_arr, np.abs(data))
    ax22.plot(coupler_ac_freq_arr, np.unwrap(np.angle(data)))
    ax23.plot(coupler_ac_freq_arr, np.real(data))
    ax24.plot(coupler_ac_freq_arr, np.imag(data))

    ax21.set_ylabel("Amplitude [FS]")
    ax22.set_ylabel("Phase [rad]")
    ax23.set_ylabel("I [FS]")
    ax24.set_ylabel("Q [FS]")
    ax2[-1].set_xlabel("Coupler AC amplitude [FS]")
    fig2.show()

    return fig1, fig2
Exemple #5
0
    def analyze(self, all_plots: bool = False):
        if self.t_arr is None:
            raise RuntimeError
        if self.store_arr is None:
            raise RuntimeError

        import matplotlib.pyplot as plt

        ret_fig = []

        idx = np.arange(IDX_LOW, IDX_HIGH)
        t_low = self.t_arr[IDX_LOW]
        t_high = self.t_arr[IDX_HIGH]

        if all_plots:
            # Plot raw store data for first iteration as a check
            fig1, ax1 = plt.subplots(2, 1, sharex=True, tight_layout=True)
            ax11, ax12 = ax1
            ax11.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax12.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax11.plot(1e9 * self.t_arr, np.abs(self.store_arr[0, 0, :]))
            ax12.plot(1e9 * self.t_arr, np.angle(self.store_arr[0, 0, :]))
            ax12.set_xlabel("Time [ns]")
            fig1.show()
            ret_fig.append(fig1)

        # Analyze Rabi
        resp_arr = np.mean(self.store_arr[:, 0, idx], axis=-1)
        data = rotate_opt(resp_arr)

        # Fit data
        popt_x, perr_x = _fit_period(self.control_amp_arr, np.real(data))
        period = popt_x[3]
        period_err = perr_x[3]
        pi_amp = period / 2
        pi_2_amp = period / 4
        if self.num_pulses > 1:
            print(f"{self.num_pulses} pulses")
        print("Tau pulse amplitude: {} +- {} FS".format(period * self.num_pulses, period_err * self.num_pulses))
        print("Pi pulse amplitude: {} +- {} FS".format(pi_amp * self.num_pulses, period_err / 2 * self.num_pulses))
        print("Pi/2 pulse amplitude: {} +- {} FS".format(pi_2_amp * self.num_pulses, period_err / 4 * self.num_pulses))

        if all_plots:
            fig2, ax2 = plt.subplots(4, 1, sharex=True, figsize=(6.4, 6.4), tight_layout=True)
            ax21, ax22, ax23, ax24 = ax2
            ax21.plot(self.control_amp_arr, np.abs(data))
            ax22.plot(self.control_amp_arr, np.angle(data))
            ax23.plot(self.control_amp_arr, np.real(data))
            ax23.plot(self.control_amp_arr, _func(self.control_amp_arr, *popt_x), '--')
            ax24.plot(self.control_amp_arr, np.imag(data))

            ax21.set_ylabel("Amplitude [FS]")
            ax22.set_ylabel("Phase [rad]")
            ax23.set_ylabel("I [FS]")
            ax24.set_ylabel("Q [FS]")
            ax2[-1].set_xlabel("Pulse amplitude [FS]")
            fig2.show()
            ret_fig.append(fig2)

        data_max = np.abs(data).max()
        unit = ""
        mult = 1.0
        if data_max < 1e-6:
            unit = "n"
            mult = 1e9
        elif data_max < 1e-3:
            unit = "μ"
            mult = 1e6
        elif data_max < 1e0:
            unit = "m"
            mult = 1e3

        fig3, ax3 = plt.subplots(tight_layout=True)
        ax3.plot(self.control_amp_arr, mult * np.real(data), '.')
        ax3.plot(self.control_amp_arr, mult * _func(self.control_amp_arr, *popt_x), '--')
        ax3.set_ylabel(f"I quadrature [{unit:s}FS]")
        ax3.set_xlabel("Pulse amplitude [FS]")
        if self.num_pulses > 1:
            ax3.set_title(f"{self.num_pulses} pulses")
        fig3.show()
        ret_fig.append(fig3)

        return ret_fig
def load(load_filename):
    with h5py.File(load_filename, "r") as h5f:
        num_averages = h5f.attrs["num_averages"]
        control_freq_1 = h5f.attrs["control_freq_1"]
        control_freq_2 = h5f.attrs["control_freq_2"]
        control_if = h5f.attrs["control_if"]
        readout_freq_1 = h5f.attrs["readout_freq_1"]
        readout_freq_2 = h5f.attrs["readout_freq_2"]
        readout_duration = h5f.attrs["readout_duration"]
        control_duration = h5f.attrs["control_duration"]
        readout_amp = h5f.attrs["readout_amp"]
        control_amp_1 = h5f.attrs["control_amp_1"]
        control_amp_2 = h5f.attrs["control_amp_2"]
        sample_duration = h5f.attrs["sample_duration"]
        wait_delay = h5f.attrs["wait_delay"]
        readout_sample_delay = h5f.attrs["readout_sample_delay"]
        coupler_dc_bias = h5f.attrs["coupler_dc_bias"]
        nr_freqs = h5f.attrs["nr_freqs"]
        nr_steps = h5f.attrs["nr_steps"]
        dt_steps = h5f.attrs["dt_steps"]
        coupler_ac_amp = h5f.attrs["coupler_ac_amp"]
        t_arr = h5f["t_arr"][()]
        store_arr = h5f["store_arr"][()]
        coupler_ac_freq_arr = h5f["coupler_ac_freq_arr"][()]
        coupler_ac_duration_arr = h5f["coupler_ac_duration_arr"][()]

        # these were added later
        try:
            # multiplexed readout
            readout_if_1 = h5f.attrs["readout_if_1"]
            readout_if_2 = h5f.attrs["readout_if_2"]
            readout_nco = h5f.attrs["readout_nco"]
        except KeyError:
            # only readout resonator 1
            readout_if_1 = 0.0
            readout_if_2 = None
            readout_nco = readout_freq_1

    t_low = 1500 * 1e-9
    t_high = 2000 * 1e-9
    idx_low = np.argmin(np.abs(t_arr - t_low))
    idx_high = np.argmin(np.abs(t_arr - t_high))
    idx = np.arange(idx_low, idx_high)

    # Plot raw store data for first iteration as a check
    # fig1, ax1 = plt.subplots(2, 1, sharex=True, tight_layout=True)
    # ax11, ax12 = ax1
    # ax11.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    # ax12.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    # ax11.plot(1e9 * t_arr, np.abs(store_arr[0, 0, :]))
    # ax12.plot(1e9 * t_arr, np.angle(store_arr[0, 0, :]))
    # ax12.set_xlabel("Time [ns]")
    # fig1.show()

    if readout_if_2 is None:
        # only readout resonator 1
        resp_arr = np.mean(store_arr[:, 0, idx], axis=-1)
        data = rotate_opt(resp_arr)
        data.shape = (nr_freqs, nr_steps)
        plot_data = data.real

        # choose limits for colorbar
        cutoff = 0.0  # %
        lowlim = np.percentile(plot_data, cutoff)
        highlim = np.percentile(plot_data, 100. - cutoff)

        # extent
        x_min = 1e9 * coupler_ac_duration_arr[0]
        x_max = 1e9 * coupler_ac_duration_arr[-1]
        dx = 1e9 * (coupler_ac_duration_arr[1] - coupler_ac_duration_arr[0])
        y_min = 1e-6 * coupler_ac_freq_arr[0]
        y_max = 1e-6 * coupler_ac_freq_arr[-1]
        dy = 1e-6 * (coupler_ac_freq_arr[1] - coupler_ac_freq_arr[0])

        fig2, ax2 = plt.subplots(tight_layout=True)
        im = ax2.imshow(
            plot_data,
            origin='lower',
            aspect='auto',
            interpolation='none',
            extent=(x_min - dx / 2, x_max + dx / 2, y_min - dy / 2,
                    y_max + dy / 2),
            vmin=lowlim,
            vmax=highlim,
        )
        ax2.set_xlabel("Coupler duration [ns]")
        ax2.set_ylabel("Coupler frequency [MHz]")
        cb = fig2.colorbar(im)
        cb.set_label("Response I quadrature [FS]")
        fig2.show()
    else:
        # multiplexed readout
        dt = t_arr[1] - t_arr[0]
        nr_samples = len(idx)
        freq_arr = np.fft.fftfreq(nr_samples, dt)
        # complex FFT should take care of upper/lower sideband
        resp_fft = np.fft.fft(store_arr[:, 0, idx], axis=-1) / len(idx)
        idx_1 = np.argmin(np.abs(freq_arr - readout_if_1))
        idx_2 = np.argmin(np.abs(freq_arr - readout_if_2))
        resp_arr_1 = 2 * resp_fft[:, idx_1]
        resp_arr_2 = 2 * resp_fft[:, idx_2]
        data_1 = rotate_opt(resp_arr_1)
        data_2 = rotate_opt(resp_arr_2)
        data_1.shape = (nr_freqs, nr_steps)
        data_2.shape = (nr_freqs, nr_steps)
        plot_data_1 = data_1.real
        plot_data_2 = data_2.real

        # convert to population
        # g_state = -0.000199191400873993
        # e_state = -0.001772512103413742
        # plot_data_1 = (data_1.real - g_state) / (e_state - g_state)
        # g_state = -0.0005096104775241157
        # e_state = 0.0010518469556880861
        # plot_data_2 = (data_2.real - g_state) / (e_state - g_state)
        if abs(np.min(plot_data_1)) > abs(np.max(plot_data_1)):
            plot_data_1 *= -1
        if abs(np.min(plot_data_2)) > abs(np.max(plot_data_2)):
            plot_data_2 *= -1

        # choose limits for colorbar
        cutoff = 0.1  # %
        lowlim_1 = np.percentile(plot_data_1, cutoff)
        highlim_1 = np.percentile(plot_data_1, 100. - cutoff)
        lowlim_2 = np.percentile(plot_data_2, cutoff)
        highlim_2 = np.percentile(plot_data_2, 100. - cutoff)
        # alldata = (np.r_[plot_data_1, plot_data_2]).ravel()
        # lowlim = np.percentile(alldata, cutoff)
        # highlim = np.percentile(alldata, 100. - cutoff)
        # lowlim_1, highlim_1 = lowlim, highlim
        # lowlim_2, highlim_2 = lowlim, highlim

        # extent
        x_min = 1e9 * coupler_ac_duration_arr[0]
        x_max = 1e9 * coupler_ac_duration_arr[-1]
        dx = 1e9 * (coupler_ac_duration_arr[1] - coupler_ac_duration_arr[0])
        y_min = 1e-6 * coupler_ac_freq_arr[0]
        y_max = 1e-6 * coupler_ac_freq_arr[-1]
        dy = 1e-6 * (coupler_ac_freq_arr[1] - coupler_ac_freq_arr[0])

        fig2, ax2 = plt.subplots(1, 2, figsize=(9.6, 4.8), tight_layout=True)
        ax21, ax22 = ax2
        im1 = ax21.imshow(
            plot_data_1,
            origin='lower',
            aspect='auto',
            interpolation='none',
            extent=(x_min - dx / 2, x_max + dx / 2, y_min - dy / 2,
                    y_max + dy / 2),
            vmin=lowlim_1,
            vmax=highlim_1,
        )
        im2 = ax22.imshow(
            plot_data_2,
            origin='lower',
            aspect='auto',
            interpolation='none',
            extent=(x_min - dx / 2, x_max + dx / 2, y_min - dy / 2,
                    y_max + dy / 2),
            vmin=lowlim_2,
            vmax=highlim_2,
        )
        ax21.set_title("Population on qubit 1")
        ax22.set_title("Population on qubit 2")
        ax21.set_xlabel("Coupler duration [ns]")
        ax22.set_xlabel("Coupler duration [ns]")
        ax21.set_ylabel("Coupler frequency [MHz]")
        # ax22.set_ylabel("Coupler frequency [MHz]")
        # ax22.yaxis.set_label_position("right")
        # ax22.yaxis.tick_right()
        for tick in ax22.get_yticklabels():
            tick.set_visible(False)
        # cb1 = fig2.colorbar(im1, ax=ax21)
        # cb1.set_ticks([0, 1])
        # cb2 = fig2.colorbar(im2, ax=ax22)
        # cb2.set_ticks([0, 1])
        # cb = fig2.colorbar(im1, ax=[ax21, ax22], use_gridspec=False)
        fig2.show()

        # Line cut at the center frequency
        idx = np.argmax(np.mean(plot_data_1, axis=-1))
        fig3, ax3 = plt.subplots(tight_layout=True)
        ax3.plot(1e9 * coupler_ac_duration_arr,
                 plot_data_1[idx, :],
                 label="qubit 1")
        ax3.plot(1e9 * coupler_ac_duration_arr,
                 plot_data_2[idx, :],
                 label="qubit 2")
        ax3.set_xlabel("Coupler duration [ns]")
        ax3.set_ylabel("Population")
        fig3.show()

    return fig2
def load(load_filename):
    with h5py.File(load_filename, "r") as h5f:
        num_averages = h5f.attrs["num_averages"]
        readout_freq = h5f.attrs["readout_freq"]
        control_freq = h5f.attrs["control_freq"]
        readout_duration = h5f.attrs["readout_duration"]
        control_duration = h5f.attrs["control_duration"]
        match_duration = h5f.attrs["match_duration"]
        readout_amp = h5f.attrs["readout_amp"]
        control_amp = h5f.attrs["control_amp"]
        sample_duration = h5f.attrs["sample_duration"]
        wait_delay = h5f.attrs["wait_delay"]
        readout_sample_delay = h5f.attrs["readout_sample_delay"]
        readout_match_delay = h5f.attrs["readout_match_delay"]
        t_arr = h5f["t_arr"][()]
        store_arr = h5f["store_arr"][()]
        match_i_data = h5f["match_i_data"][()]
        match_q_data = h5f["match_q_data"][()]
        source_code = h5f["source_code"][()]

    # t_low = 1500 * 1e-9
    # t_high = 2000 * 1e-9
    # t_span = t_high - t_low
    # idx_low = np.argmin(np.abs(t_arr - t_low))
    # idx_high = np.argmin(np.abs(t_arr - t_high))
    # idx = np.arange(idx_low, idx_high)
    # nr_samples = len(idx)
    nr_samples = len(t_arr)
    t_span = nr_samples * (t_arr[1] - t_arr[0])

    # Plot raw store data for first iteration as a check
    fig1, ax1 = plt.subplots(2, 1, sharex=True, tight_layout=True)
    ax11, ax12 = ax1
    # ax11.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    # ax12.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    ax11.plot(1e9 * t_arr, np.abs(store_arr[0, 0, :]))
    ax11.plot(1e9 * t_arr, np.abs(store_arr[1, 0, :]))
    ax12.plot(1e9 * t_arr, np.angle(store_arr[0, 0, :]))
    ax12.plot(1e9 * t_arr, np.angle(store_arr[1, 0, :]))
    ax12.set_xlabel("Time [ns]")
    fig1.show()

    # # Analyze
    data = match_i_data + 1j * match_q_data
    data = rotate_opt(data)
    data_g = data[0::2]
    data_e = data[1::2]
    x_g = data_g.real
    y_g = data_g.imag
    x_e = data_e.real
    y_e = data_e.imag
    std = max([x.std() for x in [x_g, y_g, x_e, y_e]])
    x_min = min(x_g.mean(), x_e.mean()) - 5 * std
    x_max = max(x_g.mean(), x_e.mean()) + 5 * std
    y_min = min(y_g.mean(), y_e.mean()) - 5 * std
    y_max = max(y_g.mean(), y_e.mean()) + 5 * std
    H_g, xedges, yedges = np.histogram2d(x_g, y_g, bins=100, range=[[x_min, x_max], [y_min, y_max]], density=True)
    H_e, xedges, yedges = np.histogram2d(x_e, y_e, bins=100, range=[[x_min, x_max], [y_min, y_max]], density=True)
    H_g = H_g.T
    H_e = H_e.T
    z_max = max(H_g.max(), H_e.max())

    # fig2, ax2 = plt.subplots(tight_layout=True)
    # ax2.plot(match_i_data[0::2], match_q_data[0::2], '.')
    # ax2.plot(match_i_data[1::2], match_q_data[1::2], '.')
    # ax2.plot(np.mean(match_i_data[0::2]), np.mean(match_q_data[0::2]), '.')
    # ax2.plot(np.mean(match_i_data[1::2]), np.mean(match_q_data[1::2]), '.')
    # ax2.axhline(0.0, c="tab:gray", alpha=0.25)
    # ax2.axvline(0.0, c="tab:gray", alpha=0.25)
    # fig2.show()

    fig3, ax3 = plt.subplots(1, 2, sharex=True, sharey=True, tight_layout=True, figsize=(9.6, 4.8))
    ax31, ax32 = ax3
    ax31.imshow(H_g, origin='lower', extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]], cmap="RdBu_r", vmin=-z_max, vmax=z_max)
    ax32.imshow(H_e, origin='lower', extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]], cmap="RdBu_r", vmin=-z_max, vmax=z_max)
    ax31.axhline(0.0, c="tab:gray", alpha=0.25)
    ax31.axvline(0.0, c="tab:gray", alpha=0.25)
    ax32.axhline(0.0, c="tab:gray", alpha=0.25)
    ax32.axvline(0.0, c="tab:gray", alpha=0.25)
    ax31.set_aspect('equal')
    ax32.set_aspect('equal')
    fig3.show()

    xdata = 0.5 * (xedges[1:] + xedges[:-1])
    fig4, ax4 = plt.subplots(tight_layout=True)
    ax4.plot(xdata, np.sum(H_g, axis=0))
    ax4.plot(xdata, np.sum(H_e, axis=0))
    fig4.show()

    return fig1, fig2
Exemple #8
0
def measure_t1(which_qubit):
    if which_qubit == 1:
        readout_freq = readout_freq_1
        control_freq = control_freq_1
        control_amp = control_amp_pi_1
        control_port = control_port_1
    else:
        readout_freq = readout_freq_2
        control_freq = control_freq_2
        control_amp = control_amp_pi_2
        control_port = control_port_2

    nr_delays = 128  # number of steps when changing delay between control and readout pulses
    dt_delays = 4 * 1e-6  # s, step size when changing delay between control and readout pulses

    with pulsed.Pulsed(
            address=ADDRESS,
            ext_ref_clk=EXT_REF_CLK,
            adc_mode=AdcMode.Mixed,
            adc_fsample=AdcFSample.G2,
            dac_mode=[
                DacMode.Mixed42, DacMode.Mixed02, DacMode.Mixed02,
                DacMode.Mixed02
            ],
            dac_fsample=[
                DacFSample.G10, DacFSample.G6, DacFSample.G6, DacFSample.G6
            ],
    ) as pls:
        pls.hardware.set_adc_attenuation(sample_port, 0.0)
        pls.hardware.set_dac_current(readout_port, 32_000)
        pls.hardware.set_dac_current(control_port, 32_000)
        pls.hardware.set_inv_sinc(readout_port, 0)
        pls.hardware.set_inv_sinc(control_port, 0)
        pls.hardware.configure_mixer(
            freq=readout_freq,
            in_ports=sample_port,
            out_ports=readout_port,
            sync=False,  # sync in next call
        )
        pls.hardware.configure_mixer(
            freq=control_freq,
            out_ports=control_port,
            sync=True,  # sync here
        )

        # ************************************
        # *** Setup measurement parameters ***
        # ************************************

        # Setup lookup tables for frequencies
        # we only need to use carrier 1
        pls.setup_freq_lut(
            output_ports=readout_port,
            group=0,
            frequencies=0.0,
            phases=0.0,
            phases_q=0.0,
        )
        pls.setup_freq_lut(
            output_ports=control_port,
            group=0,
            frequencies=0.0,
            phases=0.0,
            phases_q=0.0,
        )

        # Setup lookup tables for amplitudes
        pls.setup_scale_lut(
            output_ports=readout_port,
            group=0,
            scales=readout_amp,
        )
        pls.setup_scale_lut(
            output_ports=control_port,
            group=0,
            scales=control_amp,
        )

        # Setup readout and control pulses
        # use setup_long_drive to create a pulse with square envelope
        # setup_long_drive supports smooth rise and fall transitions for the pulse,
        # but we keep it simple here
        readout_pulse = pls.setup_long_drive(
            output_port=readout_port,
            group=0,
            duration=readout_duration,
            amplitude=1.0,
            amplitude_q=1.0,
            rise_time=0e-9,
            fall_time=0e-9,
        )
        control_ns = int(round(
            control_duration *
            pls.get_fs("dac")))  # number of samples in the control template
        control_envelope = sin2(control_ns)
        control_pulse = pls.setup_template(
            output_port=control_port,
            group=0,
            template=control_envelope,
            template_q=control_envelope,
            envelope=True,
        )

        # Setup sampling window
        pls.set_store_ports(sample_port)
        pls.set_store_duration(sample_duration)

        # ******************************
        # *** Program pulse sequence ***
        # ******************************
        T = 0.0  # s, start at time zero ...
        for ii in range(nr_delays):
            # pi pulse
            pls.reset_phase(T, control_port)
            pls.output_pulse(T, control_pulse)
            # Readout pulse starts after control pulse,
            # with an increasing delay
            T += control_duration + ii * dt_delays
            pls.reset_phase(T, readout_port)
            pls.output_pulse(T, readout_pulse)
            # Sampling window
            pls.store(T + readout_sample_delay)
            # Move to next iteration
            T += readout_duration
            T += wait_delay

        # **************************
        # *** Run the experiment ***
        # **************************
        pls.run(
            period=T,
            repeat_count=1,
            num_averages=num_averages,
            print_time=True,
        )
        t_arr, (data_I, data_Q) = pls.get_store_data()

    store_arr = data_I + 1j * data_Q

    idx_low = np.argmin(np.abs(t_arr - t_low))
    idx_high = np.argmin(np.abs(t_arr - t_high))
    idx = np.arange(idx_low, idx_high)

    # Analyze T1
    resp_arr = np.mean(store_arr[:, 0, idx], axis=-1)
    resp_arr = rotate_opt(resp_arr)
    delay_arr = dt_delays * np.arange(nr_delays)

    # Fit data
    popt_x, perr_x = t1_fit_simple(delay_arr, np.real(resp_arr))

    T1 = popt_x[0]
    T1_err = perr_x[0]

    return T1, T1_err
def load(load_filename):
    with h5py.File(load_filename, "r") as h5f:
        num_averages = h5f.attrs["num_averages"]
        control_freq_1 = h5f.attrs["control_freq_1"]
        control_freq_2 = h5f.attrs["control_freq_2"]
        control_if = h5f.attrs["control_if"]
        readout_freq_1 = h5f.attrs["readout_freq_1"]
        readout_freq_2 = h5f.attrs["readout_freq_2"]
        readout_duration = h5f.attrs["readout_duration"]
        control_duration = h5f.attrs["control_duration"]
        readout_amp = h5f.attrs["readout_amp"]
        control_amp_1 = h5f.attrs["control_amp_1"]
        control_amp_2 = h5f.attrs["control_amp_2"]
        sample_duration = h5f.attrs["sample_duration"]
        wait_delay = h5f.attrs["wait_delay"]
        readout_sample_delay = h5f.attrs["readout_sample_delay"]
        coupler_dc_bias = h5f.attrs["coupler_dc_bias"]
        nr_freqs = h5f.attrs["nr_freqs"]
        nr_amps = h5f.attrs["nr_amps"]
        coupler_ac_duration = h5f.attrs["coupler_ac_duration"]
        t_arr = h5f["t_arr"][()]
        store_arr = h5f["store_arr"][()]
        coupler_ac_freq_arr = h5f["coupler_ac_freq_arr"][()]
        coupler_ac_amp_arr = h5f["coupler_ac_amp_arr"][()]

    t_low = 1500 * 1e-9
    t_high = 2000 * 1e-9
    idx_low = np.argmin(np.abs(t_arr - t_low))
    idx_high = np.argmin(np.abs(t_arr - t_high))
    idx = np.arange(idx_low, idx_high)

    # # Plot raw store data for first iteration as a check
    # fig0, ax0 = plt.subplots(2, 1, sharex=True, tight_layout=True)
    # ax01, ax02 = ax0
    # ax01.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    # ax02.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
    # ax01.plot(1e9 * t_arr, np.abs(store_arr[0, 0, :]))
    # ax02.plot(1e9 * t_arr, np.angle(store_arr[0, 0, :]))
    # ax02.set_xlabel("Time [ns]")
    # fig0.show()

    resp_arr = np.mean(store_arr[:, 0, idx], axis=-1)
    data = rotate_opt(resp_arr)
    data.shape = (nr_amps, nr_freqs)
    plot_data = data.real

    # choose limits for colorbar
    cutoff = 0.0  # %
    lowlim = np.percentile(plot_data, cutoff)
    highlim = np.percentile(plot_data, 100. - cutoff)

    # extent
    x_min = 1e-6 * coupler_ac_freq_arr[0]
    x_max = 1e-6 * coupler_ac_freq_arr[-1]
    dx = 1e-6 * (coupler_ac_freq_arr[1] - coupler_ac_freq_arr[0])
    y_min = coupler_ac_amp_arr[0]
    y_max = coupler_ac_amp_arr[-1]
    dy = coupler_ac_amp_arr[1] - coupler_ac_amp_arr[0]

    fig1, ax1 = plt.subplots(tight_layout=True)
    im = ax1.imshow(
        plot_data,
        origin='lower',
        aspect='auto',
        interpolation='none',
        extent=(x_min - dx / 2, x_max + dx / 2, y_min - dy / 2,
                y_max + dy / 2),
        vmin=lowlim,
        vmax=highlim,
    )
    ax1.set_xlabel("Coupler frequency [MHz]")
    ax1.set_ylabel("Coupler amplitude [FS]")
    cb = fig1.colorbar(im)
    cb.set_label("Response amplitude [FS]")
    fig1.show()

    return fig1
    def analyze(self, all_plots: bool = False):
        if self.t_arr is None:
            raise RuntimeError
        if self.store_arr is None:
            raise RuntimeError

        import matplotlib.pyplot as plt

        ret_fig = []

        idx = np.arange(IDX_LOW, IDX_HIGH)
        t_low = self.t_arr[IDX_LOW]
        t_high = self.t_arr[IDX_HIGH]

        if all_plots:
            # Plot raw store data for first iteration as a check
            fig1, ax1 = plt.subplots(2, 1, sharex=True, tight_layout=True)
            ax11, ax12 = ax1
            ax11.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax12.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax11.plot(1e9 * self.t_arr, np.abs(self.store_arr[0, 0, :]))
            ax12.plot(1e9 * self.t_arr, np.angle(self.store_arr[0, 0, :]))
            ax12.set_xlabel("Time [ns]")
            fig1.show()
            ret_fig.append(fig1)

        # Analyze T2
        resp_arr = np.mean(self.store_arr[:, 0, idx], axis=-1)
        data = rotate_opt(resp_arr)

        # Fit data to I quadrature
        try:
            popt, perr = _fit_simple(self.delay_arr, np.real(data))

            T2 = popt[2]
            T2_err = perr[2]
            print("T2 time: {} +- {} us".format(1e6 * T2, 1e6 * T2_err))
            det = popt[3]
            det_err = perr[3]
            print("detuning: {} +- {} Hz".format(det, det_err))

            success = True
        except Exception as err:
            print("Unable to fit data!")
            print(err)
            success = False

        if all_plots:
            fig2, ax2 = plt.subplots(4, 1, sharex=True, figsize=(6.4, 6.4), tight_layout=True)
            ax21, ax22, ax23, ax24 = ax2
            ax21.plot(1e6 * self.delay_arr, np.abs(data))
            ax22.plot(1e6 * self.delay_arr, np.unwrap(np.angle(data)))
            ax23.plot(1e6 * self.delay_arr, np.real(data))
            if success:
                ax23.plot(1e6 * self.delay_arr, _func(self.delay_arr, *popt), '--')
            ax24.plot(1e6 * self.delay_arr, np.imag(data))

            ax21.set_ylabel("Amplitude [FS]")
            ax22.set_ylabel("Phase [rad]")
            ax23.set_ylabel("I [FS]")
            ax24.set_ylabel("Q [FS]")
            ax2[-1].set_xlabel("Ramsey delay [us]")
            fig2.show()
            ret_fig.append(fig2)

        data_max = np.abs(data.real).max()
        unit = ""
        mult = 1.0
        if data_max < 1e-6:
            unit = "n"
            mult = 1e9
        elif data_max < 1e-3:
            unit = "μ"
            mult = 1e6
        elif data_max < 1e0:
            unit = "m"
            mult = 1e3

        fig3, ax3 = plt.subplots(tight_layout=True)
        ax3.plot(1e6 * self.delay_arr, mult * np.real(data), '.')
        ax3.set_ylabel(f"I quadrature [{unit:s}FS]")
        ax3.set_xlabel("Ramsey delay [μs]")
        if success:
            ax3.plot(1e6 * self.delay_arr, mult * _func(self.delay_arr, *popt), '--')
            ax3.set_title(f"T2* = {1e6*T2:.0f} ± {1e6*T2_err:.0f} μs")
        fig3.show()
        ret_fig.append(fig3)

        return ret_fig
    def analyze(self, all_plots: bool = False):
        assert self.t_arr is not None
        assert self.store_arr is not None
        assert self.control_freq_arr is not None

        import matplotlib.pyplot as plt
        from scipy.optimize import curve_fit
        ret_fig = []

        idx = np.arange(IDX_LOW, IDX_HIGH)
        t_low = self.t_arr[IDX_LOW]
        t_high = self.t_arr[IDX_HIGH]

        if all_plots:
            # Plot raw store data for first iteration as a check
            fig1, ax1 = plt.subplots(2, 1, sharex=True, tight_layout=True)
            ax11, ax12 = ax1
            ax11.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax12.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax11.plot(1e9 * self.t_arr, np.abs(self.store_arr[0, 0, :]))
            ax12.plot(1e9 * self.t_arr, np.angle(self.store_arr[0, 0, :]))
            ax12.set_xlabel("Time [ns]")
            fig1.show()
            ret_fig.append(fig1)

        # Analyze
        resp_arr = np.mean(self.store_arr[:, 0, idx], axis=-1)
        data = rotate_opt(resp_arr)

        fig2, ax2 = plt.subplots(4,
                                 1,
                                 sharex=True,
                                 figsize=(6.4, 6.4),
                                 tight_layout=True)
        ax21, ax22, ax23, ax24 = ax2
        ax21.plot(1e-9 * self.control_freq_arr, np.abs(data))
        ax22.plot(1e-9 * self.control_freq_arr, np.angle(data))
        ax23.plot(1e-9 * self.control_freq_arr, np.real(data))
        try:
            data_min = data.real.min()
            data_max = data.real.max()
            data_rng = data_max - data_min
            p0 = [
                self.control_freq_center, self.control_freq_span / 4, data_rng,
                data_min
            ]
            popt, pcov = curve_fit(_gaussian, self.control_freq_arr, data.real,
                                   p0)
            ax23.plot(1e-9 * self.control_freq_arr,
                      _gaussian(self.control_freq_arr, *popt), '--')
            print(f"f0 = {popt[0]} Hz")
            print(f"sigma = {abs(popt[1])} Hz")
        except Exception:
            print("fit failed")
        ax24.plot(1e-9 * self.control_freq_arr, np.imag(data))

        ax21.set_ylabel("Amplitude [FS]")
        ax22.set_ylabel("Phase [rad]")
        ax23.set_ylabel("I [FS]")
        ax24.set_ylabel("Q [FS]")
        ax2[-1].set_xlabel("Control frequency [GHz]")
        fig2.show()
        ret_fig.append(fig2)

        return ret_fig
Exemple #12
0
    def analyze(self, quantity: str = "quadrature", linecut: bool = False, blit: bool = True):
        if self.control_freq_arr is None:
            raise RuntimeError
        if self.resp_arr is None:
            raise RuntimeError
        if quantity not in ["quadrature", "amplitude", "phase", "dB"]:
            raise ValueError

        import matplotlib.pyplot as plt
        nr_amps = len(self.control_amp_arr)

        self._AMP_IDX = nr_amps // 2

        if quantity == "dB":
            data = 20. * np.log10(np.abs(self.resp_arr))
            unit = "dBFS"
            title = "Response amplitude"
        elif quantity == "phase":
            data = np.angle(self.resp_arr)
            unit = "rad"
            title = "Response phase"
        else:
            if quantity == "amplitude":
                data = np.abs(self.resp_arr)
                title = "Response amplitude"
            else:  # "quadrature"
                data = rotate_opt(self.resp_arr).real
                title = "Response quadrature"
            data_max = np.abs(data).max()
            unit = ""
            if data_max < 1e-6:
                unit = "n"
                data *= 1e9
            elif data_max < 1e-3:
                unit = "μ"
                data *= 1e6
            elif data_max < 1e0:
                unit = "m"
                data *= 1e3
            unit += "FS"

        amp_dBFS = 20 * np.log10(self.control_amp_arr / 1.0)

        # choose limits for colorbar
        cutoff = 1.  # %
        lowlim = np.percentile(data, cutoff)
        highlim = np.percentile(data, 100. - cutoff)

        # extent
        x_min = 1e-9 * self.control_freq_arr[0]
        x_max = 1e-9 * self.control_freq_arr[-1]
        dx = 1e-9 * (self.control_freq_arr[1] - self.control_freq_arr[0])
        y_min = amp_dBFS[0]
        y_max = amp_dBFS[-1]
        dy = amp_dBFS[1] - amp_dBFS[0]

        if linecut:
            fig1 = plt.figure(tight_layout=True, figsize=(6.4, 7.2))
            gs = fig1.add_gridspec(3, 1)
            ax1 = fig1.add_subplot(gs[:-1, 0])
        else:
            fig1 = plt.figure(tight_layout=True, figsize=(6.4, 4.8))
            gs = fig1.add_gridspec(1, 1)
            ax1 = fig1.add_subplot(gs[0, 0])
        im = ax1.imshow(
            data,
            origin='lower',
            aspect='auto',
            interpolation='none',
            extent=(x_min - dx / 2, x_max + dx / 2, y_min - dy / 2, y_max + dy / 2),
            vmin=lowlim,
            vmax=highlim,
        )
        if linecut:
            line_sel = ax1.axhline(amp_dBFS[self._AMP_IDX], ls="--", c="k", lw=3, animated=blit)
        ax1.set_title(f"Probe frequency: {self.readout_freq/1e9:.2f} GHz")
        ax1.set_xlabel("Pump frequency [GHz]")
        ax1.set_ylabel("Pump amplitude [dBFS]")
        cb = fig1.colorbar(im)
        cb.set_label(f"{title:s} [{unit:s}]")

        if linecut:
            ax2 = fig1.add_subplot(gs[-1, 0])

            line_a, = ax2.plot(1e-9 * self.control_freq_arr, data[self._AMP_IDX], animated=blit)

            f_min = 1e-9 * self.control_freq_arr.min()
            f_max = 1e-9 * self.control_freq_arr.max()
            f_rng = f_max - f_min
            a_min = data.min()
            a_max = data.max()
            a_rng = a_max - a_min
            ax2.set_xlim(f_min - 0.05 * f_rng, f_max + 0.05 * f_rng)
            ax2.set_ylim(a_min - 0.05 * a_rng, a_max + 0.05 * a_rng)

            ax2.set_xlabel("Frequency [GHz]")
            ax2.set_ylabel(f"{title:s} [{unit:s}]")

            def onbuttonpress(event):
                if event.inaxes == ax1:
                    self._AMP_IDX = np.argmin(np.abs(amp_dBFS - event.ydata))
                    update()

            def onkeypress(event):
                if event.inaxes == ax1:
                    if event.key == "up":
                        self._AMP_IDX += 1
                        if self._AMP_IDX >= len(amp_dBFS):
                            self._AMP_IDX = len(amp_dBFS) - 1
                        update()
                    elif event.key == "down":
                        self._AMP_IDX -= 1
                        if self._AMP_IDX < 0:
                            self._AMP_IDX = 0
                        update()

            def update():
                line_sel.set_ydata([amp_dBFS[self._AMP_IDX], amp_dBFS[self._AMP_IDX]])
                # ax1.set_title(f"amp = {amp_arr[self._AMP_IDX]:.2e}")
                print(
                    f"drive amp {self._AMP_IDX:d}: {self.control_amp_arr[self._AMP_IDX]:.2e} FS = {amp_dBFS[self._AMP_IDX]:.1f} dBFS"
                )
                line_a.set_ydata(data[self._AMP_IDX])
                # ax2.set_title("")
                if blit:
                    fig1.canvas.restore_region(self._bg)
                    ax1.draw_artist(line_sel)
                    ax2.draw_artist(line_a)
                    fig1.canvas.blit(fig1.bbox)
                    # fig1.canvas.flush_events()
                else:
                    fig1.canvas.draw()

            fig1.canvas.mpl_connect('button_press_event', onbuttonpress)
            fig1.canvas.mpl_connect('key_press_event', onkeypress)

        fig1.show()
        if linecut and blit:
            fig1.canvas.draw()
            # fig1.canvas.flush_events()
            self._bg = fig1.canvas.copy_from_bbox(fig1.bbox)
            ax1.draw_artist(line_sel)
            ax2.draw_artist(line_a)
            fig1.canvas.blit(fig1.bbox)

        return fig1
    def analyze(self, all_plots: bool = False):
        assert self.t_arr is not None
        assert self.store_arr is not None
        assert self.control_freq_arr is not None
        assert len(self.control_freq_arr) == self.control_freq_nr

        import matplotlib.pyplot as plt

        ret_fig = []

        idx = np.arange(IDX_LOW, IDX_HIGH)
        t_low = self.t_arr[IDX_LOW]
        t_high = self.t_arr[IDX_HIGH]

        if all_plots:
            # Plot raw store data for first iteration as a check
            fig1, ax1 = plt.subplots(2, 1, sharex=True, tight_layout=True)
            ax11, ax12 = ax1
            ax11.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax12.axvspan(1e9 * t_low, 1e9 * t_high, facecolor="#dfdfdf")
            ax11.plot(1e9 * self.t_arr, np.abs(self.store_arr[0, 0, :]))
            ax12.plot(1e9 * self.t_arr, np.angle(self.store_arr[0, 0, :]))
            ax12.set_xlabel("Time [ns]")
            fig1.show()
            ret_fig.append(fig1)

        # Analyze T1
        resp_arr = np.mean(self.store_arr[:, 0, idx], axis=-1)
        resp_arr.shape = (self.control_freq_nr, len(self.delay_arr))
        data = rotate_opt(resp_arr)
        plot_data = data.real

        data_max = np.abs(plot_data).max()
        unit = ""
        mult = 1.0
        if data_max < 1e-6:
            unit = "n"
            mult = 1e9
        elif data_max < 1e-3:
            unit = "μ"
            mult = 1e6
        elif data_max < 1e0:
            unit = "m"
            mult = 1e3
        plot_data *= mult

        # choose limits for colorbar
        cutoff = 0.0  # %
        lowlim = np.percentile(plot_data, cutoff)
        highlim = np.percentile(plot_data, 100. - cutoff)

        # extent
        x_min = 1e+6 * self.delay_arr[0]
        x_max = 1e+6 * self.delay_arr[-1]
        dx = 1e+6 * (self.delay_arr[1] - self.delay_arr[0])
        y_min = 1e-9 * self.control_freq_arr[0]
        y_max = 1e-9 * self.control_freq_arr[-1]
        dy = 1e-9 * (self.control_freq_arr[1] - self.control_freq_arr[0])

        fig2, ax2 = plt.subplots(tight_layout=True)
        im = ax2.imshow(
            plot_data,
            origin='lower',
            aspect='auto',
            interpolation='none',
            extent=(x_min - dx / 2, x_max + dx / 2, y_min - dy / 2,
                    y_max + dy / 2),
            vmin=lowlim,
            vmax=highlim,
        )
        ax2.set_xlabel("Ramsey delay [μs]")
        ax2.set_ylabel("Control frequency [GHz]")
        cb = fig2.colorbar(im)
        cb.set_label(f"Response I quadrature [{unit:s}FS]")
        fig2.show()
        ret_fig.append(fig2)

        fit_freq = np.zeros_like(self.control_freq_arr)
        for jj in range(self.control_freq_nr):
            try:
                res, _err = _fit_simple(self.delay_arr, plot_data[jj])
                fit_freq[jj] = np.abs(res[3])
            except Exception:
                fit_freq[jj] = np.nan

        n_fit = self.control_freq_nr // 4
        pfit1 = np.polyfit(self.control_freq_arr[:n_fit], fit_freq[:n_fit], 1)
        pfit2 = np.polyfit(self.control_freq_arr[-n_fit:], fit_freq[-n_fit:],
                           1)
        x0 = np.roots(pfit1 - pfit2)[0]

        fig3, ax3 = plt.subplots(tight_layout=True)
        ax3.plot(self.control_freq_arr, fit_freq, '.')
        ax3.set_ylabel("Fitted detuning [Hz]")
        ax3.set_xlabel("Control frequency [Hz]$]")
        fig3.show()
        _lims = ax3.axis()
        ax3.plot(
            self.control_freq_arr,
            np.polyval(pfit1, self.control_freq_arr),
            '--',
            c='tab:orange',
        )
        ax3.plot(
            self.control_freq_arr,
            np.polyval(pfit2, self.control_freq_arr),
            '--',
            c='tab:green',
        )
        ax3.axhline(0.0, ls='--', c='tab:gray')
        ax3.axvline(x0, ls='--', c='tab:gray')
        ax3.axis(_lims)
        fig3.canvas.draw()
        print(f"Fitted qubit frequency: {x0} Hz")
        ret_fig.append(fig3)

        return ret_fig