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
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
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
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