Ejemplo n.º 1
0
def transmissionfit(f_data,z_data,fr,Qr): #not tested
    '''
    phasefit enhanced by circlefit method
    '''
    xc, yc, r0 = rt.fit_circle(z_data)
    zc = np.complex(xc,yc)
    fitparams = rt.phase_fit_nooffset(f_data,rt.center(z_data,zc),Qr,fr)
    Qr, fr = fitparams[0]
    results = {"Qr":Qr,"fr":fr}
    p = fr, Qr
    chi_square, cov = rt.get_cov(rt.residuals_transm_ideal,f_data,z_data,p)
    if cov!=None:
        errors = [np.sqrt(cov[i][i]) for i in range(len(cov))]
        results.update({"fr_err":errors[0],"Qr_err":errors[1],"chi_square":chi_square})
    return results
Ejemplo n.º 2
0
def do_calibration(f_data,z_data,ignoreslope=True,guessdelay=True):
    '''
    performs an automated calibration and tries to determine the prefactors a, alpha, delay
    fr, Qr, and a possible slope are extra information, which can be used as start parameters for subsequent fits
    see also "do_normalization"
    the calibration procedure works for transmission line resonators as well
    '''
    delay, params = get_delay(f_data,z_data,ignoreslope=ignoreslope,guess=guessdelay)
    z_data = (z_data-params[1]*(f_data-params[4]))*np.exp(2.*1j*np.pi*delay*f_data)
    xc, yc, r0 = rt.fit_circle(z_data)
    zc = np.complex(xc,yc)
    fitparams = rt.phase_fit(f_data,rt.center(z_data,zc),0.,np.absolute(params[5]),params[4])
    theta, Qr, fr = fitparams
    beta = rt.periodic_boundary(theta+np.pi,np.pi)
    offrespoint = np.complex((xc+r0*np.cos(beta)),(yc+r0*np.sin(beta)))
    alpha = np.angle(offrespoint)
    a = np.absolute(offrespoint)
    return delay, a, alpha, fr, Qr, params[1], params[4]
Ejemplo n.º 3
0
def circlefit(f_data,z_data,fr=None,Qr=None,refine_results=False,calc_errors=True):
    '''
    performs a circle fit on a frequency vs. complex resonator scattering data set
    Data has to be normalized!!
    INPUT:
    f_data,z_data: input data (frequency, complex S21 data)
    OUTPUT:
    outpus a dictionary {key:value} consisting of the fit values, errors and status information about the fit
    values: {"phi0":phi0, "Qr":Qr, "absolute(Qc)":absQc, "Qi": Qi, "electronic_delay":delay, "complexQc":complQc, "resonance_freq":fr, "prefactor_a":a, "prefactor_alpha":alpha}
    errors: {"phi0_err":phi0_err, "Qr_err":Qr_err, "absolute(Qc)_err":absQc_err, "Qi_err": Qi_err, "electronic_delay_err":delay_err, "resonance_freq_err":fr_err, "prefactor_a_err":a_err, "prefactor_alpha_err":alpha_err}
    for details, see:
        [1] (not diameter corrected) Jiansong Gao, "The Physics of Superconducting Microwave Resonators" (PhD Thesis), Appendix E, California Institute of Technology, (2008)
        [2] (diameter corrected) M. S. Khalil, et. al., J. Appl. Phys. 111, 054510 (2012)
        [3] (fitting techniques) N. CHERNOV AND C. LESORT, "Least Squares Fitting of Circles", Journal of Mathematical Imaging and Vision 23, 239, (2005)
        [4] (further fitting techniques) P. J. Petersan, S. M. Anlage, J. Appl. Phys, 84, 3392 (1998)
    the program fits the circle with the algebraic technique described in [3], the rest of the fitting is done with the scipy.optimize least square fitting toolbox
    also, check out [5] S. Probst et al. "Efficient and reliable analysis of noisy complex scatterung resonator data for superconducting quantum circuits" (in preparation)
    '''

    if fr==None: fr=f_data[np.argmin(np.absolute(z_data))]
    if Qr==None: Qr=1e6
    xc, yc, r0 = rt.fit_circle(z_data,refine_results=refine_results)
    phi0 = -np.arcsin(yc/r0)
    theta0 = rt.periodic_boundary(phi0+np.pi,np.pi)
    z_data_corr = rt.center(z_data,np.complex(xc,yc))
    theta0, Qr, fr = rt.phase_fit(f_data,z_data_corr,theta0,Qr,fr)
    #print "Qr from phasefit is: " + str(Qr)
    absQc = Qr/(2.*r0)
    complQc = absQc*np.exp(1j*((-1.)*phi0))
    Qc = 1./(1./complQc).real   # here, taking the real part of (1/complQc) from diameter correction method
    Qi_dia_corr = 1./(1./Qr-1./Qc)
    Qi_no_corr = 1./(1./Qr-1./absQc)

    results = {"Qi_dia_corr":Qi_dia_corr,"Qi_no_corr":Qi_no_corr,"absQc":absQc,"Qc_dia_corr":Qc,"Qr":Qr,"fr":fr,"theta0":theta0,"phi0":phi0}

    #calculation of the error
    p = [fr,absQc,Qr,phi0]
    #chi_square, errors = rt.get_errors(rt.residuals_notch_ideal,f_data,z_data,p)
    if calc_errors==True:
        chi_square, cov = rt.get_cov_fast(f_data,z_data,p)
        #chi_square, cov = rt.get_cov(rt.residuals_notch_ideal,f_data,z_data,p)

        if cov!=None:
            errors = np.sqrt(np.diagonal(cov))
            fr_err,absQc_err,Qr_err,phi0_err = errors
            #calc Qi with error prop (sum the squares of the variances and covariaces)
            dQr = 1./((1./Qr-1./absQc)**2*Qr**2)
            dabsQc = - 1./((1./Qr-1./absQc)**2*absQc**2)
            Qi_no_corr_err = np.sqrt((dQr**2*cov[2][2]) + (dabsQc**2*cov[1][1])+(2*dQr*dabsQc*cov[2][1]))  #with correlations
            #calc Qi dia corr with error prop
            dQr = 1/((1/Qr-np.cos(phi0)/absQc)**2 *Qr**2)
            dabsQc = -np.cos(phi0)/((1/Qr-np.cos(phi0)/absQc)**2 *absQc**2)
            dphi0 = -np.sin(phi0)/((1/Qr-np.cos(phi0)/absQc)**2 *absQc)
            ##err1 = ( (dQr*cov[2][2])**2 + (dabsQc*cov[1][1])**2 + (dphi0*cov[3][3])**2 )
            err1 = ( (dQr**2*cov[2][2]) + (dabsQc**2*cov[1][1]) + (dphi0**2*cov[3][3]) )
            err2 = ( dQr*dabsQc*cov[2][1] + dQr*dphi0*cov[2][3] + dabsQc*dphi0*cov[1][3] )
            Qi_dia_corr_err =  np.sqrt(err1+2*err2)  # including correlations
            errors = {"phi0_err":phi0_err, "Qr_err":Qr_err, "absQc_err":absQc_err, "fr_err":fr_err,"chi_square":chi_square,"Qi_no_corr_err":Qi_no_corr_err,"Qi_dia_corr_err": Qi_dia_corr_err}
            results.update( errors )
        else:
            print "WARNING: Error calculation failed!"
    else:
        #just calc chisquared:
        fun2 = lambda x: rt.residuals_notch_ideal(x,f_data,z_data)**2
        chi_square = 1./float(len(f_data)-len(p)) * (fun2(p)).sum()
        errors = {"chi_square":chi_square}
        results.update(errors)

    return results