Fast multiplexed superconducting qubit readout with intrinsic Purcell filtering
Here we aim to reproduce the main results presented in this paper by using QuLTRA. The core idea is to design a notch filter at the qubit frequency by coupling the readout resonator and the filter resonator through a mutual inductive (MTL) coupling. The article provides almost all the necessary elements to recreate this circuit in QuLTRA. We extract the qubit capacitance, inductance, and coupling capacitance from the mode frequency and anharmonicity. The lengths of the resonators and the coupler, along with the widths and gaps of the transmission lines, are explicitly reported in the paper.
In the first task, after defining all the design parameters, we will show the Purcell decay as a function of the qubit inductance variation. The results demonstrate that when the qubit frequency is aligned with the notch frequency, the Purcell decay becomes significantly enhanced.
[1]:
import numpy as np
import qultra as qu
[2]:
e = 1.60217657e-19 # electron charge
h = 6.62606957e-34 # Plank's
alpha=326e6
f=8.032e9
C=e**2/2/h/alpha #Cj+Cg
L=1/C/(2*np.pi*f)**2 #Lj
print(C/1e-15)
print(L/1e-9)
59.41788181803965
6.608086177178166
[3]:
Cj=55.5e-15
L=6.6e-9
Cg=4e-15
Ck=10e-15 #coupling to the feedline
#all these values are available in the original article
Z0=66
gap=[7.5,7.5,7.5,7.5]
width=[5,5.5,5]
l_r0=974e-6
l_rs=1617e-6
l_p0=759e-6
l_ps=1659e-6
l_c=318e-6
[4]:
variations = np.linspace(-0.5, 0.5, 60) #percentage variation
Tp=[]
for var in variations:
Lj=L+L*var
net=[qu.C(0,1,Cj),qu.J(0,1,Lj),qu.C(1,2,Cg),qu.CPW(2,3,l_r0,Z0),qu.CPW_coupler([3,4,5,6],gap,width,l_c),qu.CPW(4,0,l_rs,Z0),qu.CPW(5,7,l_p0,Z0),qu.CPW(6,0,l_ps,Z0),qu.C(7,8,Ck),qu.R(8,0,50)]
complete_notch=qu.QCircuit(net,5,12)
k=complete_notch.kappa()
Tp.append(1/2/np.pi/(k[0]*1e6)) #take qubit kappa
[5]:
import matplotlib.pyplot as plt
plt.plot(variations*100, Tp, marker='o')
plt.xlabel('Percentage qubit inductance variation', fontsize=18)
plt.ylabel('Qubit Purcell decay [s]',fontsize=18)
#plt.title('Qubit Purcell decay vs Qubit inductance Variation',fontsize=18)
plt.xticks(fontsize=18)
plt.yticks(fontsize=18)
plt.grid(True)
plt.show()

[6]:
i=np.argmax(np.array(Tp))
Lj=L+L*variations[i]
net=[qu.C(0,1,Cj),qu.J(0,1,Lj),qu.C(1,2,Cg),qu.CPW(2,3,l_r0,Z0),qu.CPW_coupler([3,4,5,6],gap,width,l_c),qu.CPW(4,0,l_rs,Z0),qu.CPW(5,7,l_p0,Z0),qu.CPW(6,0,l_ps,Z0),qu.C(7,8,Ck),qu.R(8,0,50)]
complete_notch=qu.QCircuit(net,5,12)
complete_notch.show_all()
print('Purcell decay time for the optimal resonator length: ', Tp[i], 's')
+------+------------+-----------+-----------+
| Mode | Freq [GHz] | k [MHz] | Q |
+------+------------+-----------+-----------+
| 1 | 8.19e+00 | -1.94e-09 | -4.21e+12 |
| 2 | 1.01e+01 | -6.40e-02 | -1.57e+05 |
| 3 | 1.05e+01 | -1.89e+01 | -5.53e+02 |
+------+------------+-----------+-----------+
Chi matrix [MHz]:
+------+----------+----------+----------+
| Mode | 1 | 2 | 3 |
+------+----------+----------+----------+
| 1 | 3.19e+02 | 6.65e+00 | 2.80e-02 |
| 2 | 6.65e+00 | 3.47e-02 | 2.92e-04 |
| 3 | 2.80e-02 | 2.92e-04 | 6.14e-07 |
+------+----------+----------+----------+
Purcell decay time for the optimal resonator length: 81.84390238332135 s
The article shows $ Z_{12} $ of the two-port composed only of the two coupled resonators. In the graph, the resonant frequencies of the two resonators and the notch frequency can be clearly identified. Here, we aim to reproduce the same result. After constructing the circuit, we will compute the total admittance matrix, from which we will extract the impedance matrix of the two-port, in order to demonstrate that QuLTRA provides consistent results.
[7]:
Z0=66
gap=[7.5,7.5,7.5,7.5]
width=[5,5.5,5]
l_r0=974e-6
l_rs=1617e-6
l_p0=759e-6
l_ps=1659e-6
l_c=318e-6
net=[qu.CPW(1,2,l_r0,Z0),qu.CPW_coupler([2,3,4,5],gap,width,l_c),qu.CPW(3,0,l_rs,Z0),qu.CPW(4,6,l_p0,Z0),qu.CPW(5,0,l_ps,Z0)]
eth_notch=qu.QCircuit(net,6,12)
[10]:
frequencies=np.arange(6,12,0.001)
#frequencies=np.linspace(6,12,5001)
port=[0,5]
Z_12=[]
for f in frequencies:
Y=eth_notch.build_total_Y_matrix(1j*2*np.pi*1e9*f)
Z=np.linalg.inv(Y)
Z_submatrix=np.zeros((len(port),len(port)),dtype=complex)
for i in range(len(port)):
for j in range(len(port)):
Z_submatrix[i,j]=Z[port[i],port[j]]
Z_12.append(20*np.log10((abs(Z_submatrix[1,0].imag))))
[11]:
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 5))
plt.plot(frequencies, Z_12, '-', color='blue')
# Etichette e legenda
plt.xlabel('Frequency [GHz]', fontsize='18')
plt.ylabel('$Z_{12}$ [dB]', fontsize='18')
plt.grid(True)
#plt.tight_layout()
plt.xticks(fontsize='18')
plt.yticks(fontsize='18')
# Mostra il grafico
plt.show()

[ ]:
[ ]: