[docs]@dataclassclassDispersiveShiftQutritResults(Results):"""Dispersive shift outputs."""frequency_state_zero:dict[QubitId,float]"""State zero frequency."""frequency_state_one:dict[QubitId,float]"""State one frequency."""frequency_state_two:dict[QubitId,float]"""State two frequency."""fitted_parameters_state_zero:dict[QubitId,list[float]]"""Fitted parameters state zero."""fitted_parameters_state_one:dict[QubitId,list[float]]"""Fitted parameters state one."""fitted_parameters_state_two:dict[QubitId,list[float]]"""Fitted parameters state one."""@propertydefstate_zero(self):return{key:valueforkey,valueinasdict(self).items()if"zero"inkey}@propertydefstate_one(self):return{key:valueforkey,valueinasdict(self).items()if"one"inkey}@propertydefstate_two(self):return{key:valueforkey,valueinasdict(self).items()if"two"inkey}
[docs]def_acquisition(params:DispersiveShiftParameters,platform:CalibrationPlatform,targets:list[QubitId],)->DispersiveShiftQutritData:r""" Data acquisition for dispersive shift qutrit experiment. Perform spectroscopy on the readout resonator, with the qubit in ground, excited state and second excited state showing the resonator shift produced by the coupling between the resonator and the qubit. Args: params (DispersiveShiftParameters): experiment's parameters platform (CalibrationPlatform): Qibolab platform object targets (list): list of target qubits to perform the action """sequence_0=PulseSequence()sequence_1=PulseSequence()sequence_2=PulseSequence()forqubitintargets:natives=platform.natives.single_qubit[qubit]# prepare 0 and measuresequence_0+=natives.MZ()# prepare 1 and measuresequence_1+=natives.RX()|natives.MZ()# prepare 2 and measureassertnatives.RX12isnotNone,f"Missing RX12 calibration for qubit {qubit}"sequence_2+=(natives.RX()+natives.RX12())|natives.MZ()# define the parameter to sweep and its range:delta_frequency_range=np.arange(-params.freq_width/2,params.freq_width/2,params.freq_step)data=DispersiveShiftQutritData(resonator_type=platform.resonator_type)sweepers=[Sweeper(parameter=Parameter.frequency,values=readout_frequency(q,platform,state=1)+delta_frequency_range,channels=[platform.qubits[q].probe],)forqintargets]results=platform.execute([sequence_0,sequence_1,sequence_2],[sweepers],nshots=params.nshots,relaxation_time=params.relaxation_time,acquisition_type=AcquisitionType.INTEGRATION,averaging_mode=AveragingMode.CYCLIC,)forqubitintargets:forstate,sequenceinenumerate([sequence_0,sequence_1,sequence_2]):ro_pulse=list(sequence.channel(platform.qubits[qubit].acquisition))[-1]result=results[ro_pulse.id]data.register_qubit(ResSpecType,(qubit,state),dict(freq=readout_frequency(qubit,platform,state=1)+delta_frequency_range,signal=magnitude(result),phase=phase(result),),)returndata
[docs]def_fit(data:DispersiveShiftQutritData)->DispersiveShiftQutritResults:"""Post-Processing for dispersive shift"""qubits=data.qubitsfrequency_0={}frequency_1={}frequency_2={}fitted_parameters_0={}fitted_parameters_1={}fitted_parameters_2={}foriinrange(3):forqubitinqubits:data_i=data[qubit,i]fit_result=lorentzian_fit(data_i,resonator_type=data.resonator_type,fit="resonator")iffit_resultisnotNone:ifi==0:frequency_0[qubit],fitted_parameters_0[qubit],_=fit_resultelifi==1:frequency_1[qubit],fitted_parameters_1[qubit],_=fit_resultelse:frequency_2[qubit],fitted_parameters_2[qubit],_=fit_resultreturnDispersiveShiftQutritResults(frequency_state_zero=frequency_0,frequency_state_one=frequency_1,frequency_state_two=frequency_2,fitted_parameters_state_one=fitted_parameters_1,fitted_parameters_state_zero=fitted_parameters_0,fitted_parameters_state_two=fitted_parameters_2,)
[docs]def_plot(data:DispersiveShiftQutritData,target:QubitId,fit:DispersiveShiftQutritResults):"""Plotting function for dispersive shift."""figures=[]fig=make_subplots(rows=1,cols=2,horizontal_spacing=0.1,vertical_spacing=0.1,subplot_titles=("Signal [a.u.]","phase [rad]",),)# iterate over multiple data foldersfitting_report=""data_0=data[target,0]data_1=data[target,1]data_2=data[target,2]fit_data_0=fit.state_zeroiffitisnotNoneelseNonefit_data_1=fit.state_oneiffitisnotNoneelseNonefit_data_2=fit.state_twoiffitisnotNoneelseNonefori,label,q_data,data_fitinlist(zip((0,1,2),("State 0","State 1","State 2"),(data_0,data_1,data_2),(fit_data_0,fit_data_1,fit_data_2),)):opacity=1frequencies=q_data.freq*HZ_TO_GHZfig.add_trace(go.Scatter(x=frequencies,y=q_data.signal,opacity=opacity,name=f"{label}",showlegend=True,legendgroup=f"{label}",),row=1,col=1,)fig.add_trace(go.Scatter(x=frequencies,y=q_data.phase,opacity=opacity,showlegend=False,legendgroup=f"{label}",),row=1,col=2,)iffitisnotNone:freqrange=np.linspace(min(frequencies),max(frequencies),2*len(q_data),)params=data_fit[("fitted_parameters_state_zero"ifi==0else("fitted_parameters_state_one"ifi==1else"fitted_parameters_state_two"))][target]fig.add_trace(go.Scatter(x=freqrange,y=lorentzian(freqrange,*params),name=f"{label} Fit",line=go.scatter.Line(dash="dot"),),row=1,col=1,)iffitisnotNone:fitting_report=table_html(table_dict(target,["State Zero Frequency [Hz]","State One Frequency [Hz]","State Two Frequency [Hz]",],np.round([fit_data_0["frequency_state_zero"][target]*GHZ_TO_HZ,fit_data_1["frequency_state_one"][target]*GHZ_TO_HZ,fit_data_2["frequency_state_two"][target]*GHZ_TO_HZ,]),))fig.update_layout(showlegend=True,xaxis_title="Frequency [GHz]",yaxis_title="Signal [a.u.]",xaxis2_title="Frequency [GHz]",yaxis2_title="Phase [rad]",)figures.append(fig)returnfigures,fitting_report