def GetFreeCoupling_Eq(MADTwiss,FilesX,FilesY,Qh,Qv,Qx,Qy,psih_ac2bpmac,psiv_ac2bpmac,bd,acdipole,oa):

    #-- Details of this algorithms is in http://www.agsrhichome.bnl.gov/AP/ap_notes/ap_note_410.pdf
    
    #-- Check linx/liny files, may be redundant
    if len(FilesX)!=len(FilesY): return [{},[]]

    #-- Select common BPMs
    bpm=utils.bpm.model_intersect(utils.bpm.intersect(FilesX + FilesY), MADTwiss)
    bpm=[(b[0],str.upper(b[1])) for b in bpm]

    #-- Last BPM on the same turn to fix the phase shift by Q for exp data of LHC
    #if op=="1" and bd== 1: s_lastbpm=MADTwiss.S[MADTwiss.indx['BPMSW.1L2.B1']]
    #if op=="1" and bd==-1: s_lastbpm=MADTwiss.S[MADTwiss.indx['BPMSW.1L8.B2']]

    #-- Determine the BPM closest to the AC dipole and its position
    #BPMYB.6L4.B1 BPMYA.5L4.B1
    # BPMWA.B5L4.B1

    horBPMsCopensation =[]
    verBPMsCopensation = []
    #bpmac1_h=psih_ac2bpmac.keys()[0]
    #bpmac2_h=psih_ac2bpmac.keys()[1]

    #bpmac1_v = psiv_ac2bpmac.keys()[0]
    #bpmac2_v = psiv_ac2bpmac.keys()[1]
    for key in psih_ac2bpmac:
        if(key in list(zip(*bpm)[1])): 
            horBPMsCopensation.append(key)
            verBPMsCopensation.append(key)    
    fqwList = []
    for g in range(0, len(horBPMsCopensation)):
        k_bpmac_h =list(zip(*bpm)[1]).index(horBPMsCopensation[g])
        bpmac_h=horBPMsCopensation[g]
        
        k_bpmac_v=list(zip(*bpm)[1]).index(verBPMsCopensation[g])
        bpmac_v=verBPMsCopensation[g] 
        '''
        try:
            k_bpmac_h=list(zip(*bpm)[1]).index(bpmac1_h)
            bpmac_h=bpmac1_h
        except:
            try:
                k_bpmac_h=list(zip(*bpm)[1]).index(bpmac2_h)
                bpmac_h=bpmac2_h
            except:
                print >> sys.stderr,'WARN: BPMs next to AC dipoles or ADT missing. AC or ADT dipole effects not calculated with analytic eqs for coupling'
                return [{},[]]
        #      if 'B5R4' in b: bpmac1=b
        #if 'A5R4' in b: bpmac2=b
        try:
            k_bpmac_v=list(zip(*bpm)[1]).index(bpmac1_v)
            bpmac_v=bpmac1_v
        except:
            try:
                k_bpmac_v=list(zip(*bpm)[1]).index(bpmac2_v)
                bpmac_v=bpmac2_v
            except:
                print >> sys.stderr,'WARN: BPMs next to AC dipoles or ADT missing. AC dipole or ADT effects not calculated with analytic eqs for coupling'
                return [{},[]]
        print k_bpmac_v, bpmac_v
        print k_bpmac_h, bpmac_h
        '''
       #-- Global parameters of the driven motion
        dh =Qh-Qx
        dv =Qv-Qy
        rh =sin(np.pi*(Qh-Qx))/sin(np.pi*(Qh+Qx))
        rv =sin(np.pi*(Qv-Qy))/sin(np.pi*(Qv+Qy))
        rch=sin(np.pi*(Qh-Qy))/sin(np.pi*(Qh+Qy))
        rcv=sin(np.pi*(Qx-Qv))/sin(np.pi*(Qx+Qv))
    
        #-- Loop for files
        f1001Abs =np.zeros((len(bpm),len(FilesX)))
        f1010Abs =np.zeros((len(bpm),len(FilesX)))
        f1001xArg=np.zeros((len(bpm),len(FilesX)))
        f1001yArg=np.zeros((len(bpm),len(FilesX)))
        f1010xArg=np.zeros((len(bpm),len(FilesX)))
        f1010yArg=np.zeros((len(bpm),len(FilesX)))
        for i in range(len(FilesX)):
    
            #-- Read amplitudes and phases
            amph  =     np.array([FilesX[i].AMPX[FilesX[i].indx[b[1]]]    for b in bpm])
            ampv  =     np.array([FilesY[i].AMPY[FilesY[i].indx[b[1]]]    for b in bpm])
            amph01=     np.array([FilesX[i].AMP01[FilesX[i].indx[b[1]]]   for b in bpm])
            ampv10=     np.array([FilesY[i].AMP10[FilesY[i].indx[b[1]]]   for b in bpm])
            psih  =2*np.pi*np.array([FilesX[i].MUX[FilesX[i].indx[b[1]]]     for b in bpm])
            psiv  =2*np.pi*np.array([FilesY[i].MUY[FilesY[i].indx[b[1]]]     for b in bpm])
            psih01=2*np.pi*np.array([FilesX[i].PHASE01[FilesX[i].indx[b[1]]] for b in bpm])
            psiv10=2*np.pi*np.array([FilesY[i].PHASE10[FilesY[i].indx[b[1]]] for b in bpm])
            #-- I'm not sure this is correct for the coupling so I comment out this part for now (by RM 9/30/11).
            #for k in range(len(bpm)):
            #       try:
            #               if bpm[k][0]>s_lastbpm:
            #                       psih[k]  +=bd*2*np.pi*Qh  #-- To fix the phase shift by Qh
            #                       psiv[k]  +=bd*2*np.pi*Qv  #-- To fix the phase shift by Qv
            #                       psih01[k]+=bd*2*np.pi*Qv  #-- To fix the phase shift by Qv
            #                       psiv10[k]+=bd*2*np.pi*Qh  #-- To fix the phase shift by Qh
            #       except: pass
    
            #-- Construct Fourier components
            #   * be careful for that the note is based on x+i(alf*x*bet*x')).
            #   * Calculating Eqs (87)-(92) by using Eqs (47) & (48) (but in the Fourier space) in the note.
            #   * Note that amph(v)01 is normalized by amph(v) and it is un-normalized in the following.
            dpsih  =np.append(psih[1:]  ,2*np.pi*Qh+psih[0]  )-psih
            dpsiv  =np.append(psiv[1:]  ,2*np.pi*Qv+psiv[0]  )-psiv
            dpsih01=np.append(psih01[1:],2*np.pi*Qv+psih01[0])-psih01
            dpsiv10=np.append(psiv10[1:],2*np.pi*Qh+psiv10[0])-psiv10
    
            X_m10=2*amph*np.exp(-1j*psih)
            Y_0m1=2*ampv*np.exp(-1j*psiv)
            X_0m1=amph*np.exp(-1j*psih01)/(1j*sin(dpsih))*(amph01*np.exp(1j*dpsih)-np.append(amph01[1:],amph01[0])*np.exp(-1j*dpsih01))
            X_0p1=amph*np.exp( 1j*psih01)/(1j*sin(dpsih))*(amph01*np.exp(1j*dpsih)-np.append(amph01[1:],amph01[0])*np.exp( 1j*dpsih01))
            Y_m10=ampv*np.exp(-1j*psiv10)/(1j*sin(dpsiv))*(ampv10*np.exp(1j*dpsiv)-np.append(ampv10[1:],ampv10[0])*np.exp(-1j*dpsiv10))
            Y_p10=ampv*np.exp( 1j*psiv10)/(1j*sin(dpsiv))*(ampv10*np.exp(1j*dpsiv)-np.append(ampv10[1:],ampv10[0])*np.exp( 1j*dpsiv10))
    
            #-- Construct f1001hv, f1001vh, f1010hv (these include math.sqrt(betv/beth) or math.sqrt(beth/betv))
            f1001hv=-np.conjugate(1/(2j)*Y_m10/X_m10)  #-- - sign from the different def
            f1001vh=-1/(2j)*X_0m1/Y_0m1             #-- - sign from the different def
            f1010hv=-1/(2j)*Y_p10/np.conjugate(X_m10)  #-- - sign from the different def
            f1010vh=-1/(2j)*X_0p1/np.conjugate(Y_0m1)  #-- - sign from the different def
    ##              f1001hv=conjugate(1/(2j)*Y_m10/X_m10)
    ##              f1001vh=1/(2j)*X_0m1/Y_0m1
    ##              f1010hv=1/(2j)*Y_p10/conjugate(X_m10)
    ##              f1010vh=1/(2j)*X_0p1/conjugate(Y_0m1)
    
            #-- Construct phases psih, psiv, Psih, Psiv w.r.t. the AC dipole
            psih=psih-(psih[k_bpmac_h]-psih_ac2bpmac[bpmac_h]) 
            psiv=psiv-(psiv[k_bpmac_v]-psiv_ac2bpmac[bpmac_v]) 
            print('the phase to the device', k_bpmac_h, psih[k_bpmac_h], bpmac_h, (psih[k_bpmac_h]-psih_ac2bpmac[bpmac_h]))
            Psih=psih-np.pi*Qh
            Psih[:k_bpmac_h]=Psih[:k_bpmac_h]+2*np.pi*Qh
            Psiv=psiv-np.pi*Qv
            Psiv[:k_bpmac_v]=Psiv[:k_bpmac_v]+2*np.pi*Qv
    
            Psix=np.arctan((1-rh)/(1+rh)*np.tan(Psih))%np.pi
            Psiy=np.arctan((1-rv)/(1+rv)*np.tan(Psiv))%np.pi
            for k in range(len(bpm)):
                if Psih[k]%(2*np.pi)>np.pi: Psix[k]=Psix[k]+np.pi
                if Psiv[k]%(2*np.pi)>np.pi: Psiy[k]=Psiy[k]+np.pi
    
            psix=Psix-np.pi*Qx
            psix[k_bpmac_h:]=psix[k_bpmac_h:]+2*np.pi*Qx
            psiy=Psiy-np.pi*Qy
            psiy[k_bpmac_v:]=psiy[k_bpmac_v:]+2*np.pi*Qy
    
            #-- Construct f1001h, f1001v, f1010h, f1010v (these include math.sqrt(betv/beth) or math.sqrt(beth/betv))
            f1001h=1/math.sqrt(1-rv**2)*(np.exp(-1j*(Psiv-Psiy))*f1001hv+rv*np.exp( 1j*(Psiv+Psiy))*f1010hv)
            f1010h=1/math.sqrt(1-rv**2)*(np.exp( 1j*(Psiv-Psiy))*f1010hv+rv*np.exp(-1j*(Psiv+Psiy))*f1001hv)
            f1001v=1/math.sqrt(1-rh**2)*(np.exp( 1j*(Psih-Psix))*f1001vh+rh*np.exp(-1j*(Psih+Psix))*np.conjugate(f1010vh))
            f1010v=1/math.sqrt(1-rh**2)*(np.exp( 1j*(Psih-Psix))*f1010vh+rh*np.exp(-1j*(Psih+Psix))*np.conjugate(f1001vh))
    
            #-- Construct f1001 and f1010 from h and v BPMs (these include math.sqrt(betv/beth) or math.sqrt(beth/betv))
            g1001h          =np.exp(-1j*((psih-psih[k_bpmac_h])-(psiy-psiy[k_bpmac_v])))*(ampv/amph*amph[k_bpmac_h]/ampv[k_bpmac_v])*f1001h[k_bpmac_h]
            g1001h[:k_bpmac_h]=1/(np.exp(2*np.pi*1j*(Qh-Qy))-1)*(f1001h-g1001h)[:k_bpmac_h]
            g1001h[k_bpmac_h:]=1/(1-np.exp(-2*np.pi*1j*(Qh-Qy)))*(f1001h-g1001h)[k_bpmac_h:]
    
            g1010h          =np.exp(-1j*((psih-psih[k_bpmac_h])+(psiy-psiy[k_bpmac_v])))*(ampv/amph*amph[k_bpmac_h]/ampv[k_bpmac_v])*f1010h[k_bpmac_h]
            g1010h[:k_bpmac_h]=1/(np.exp(2*np.pi*1j*(Qh+Qy))-1)*(f1010h-g1010h)[:k_bpmac_h]
            g1010h[k_bpmac_h:]=1/(1-np.exp(-2*np.pi*1j*(Qh+Qy)))*(f1010h-g1010h)[k_bpmac_h:]
    
            g1001v          =np.exp(-1j*((psix-psix[k_bpmac_h])-(psiv-psiv[k_bpmac_v])))*(amph/ampv*ampv[k_bpmac_v]/amph[k_bpmac_h])*f1001v[k_bpmac_v]
            g1001v[:k_bpmac_v]=1/(np.exp(2*np.pi*1j*(Qx-Qv))-1)*(f1001v-g1001v)[:k_bpmac_v]
            g1001v[k_bpmac_v:]=1/(1-np.exp(-2*np.pi*1j*(Qx-Qv)))*(f1001v-g1001v)[k_bpmac_v:]
    
            g1010v          =np.exp(-1j*((psix-psix[k_bpmac_h])+(psiv-psiv[k_bpmac_v])))*(amph/ampv*ampv[k_bpmac_v]/amph[k_bpmac_h])*f1010v[k_bpmac_v]
            g1010v[:k_bpmac_v]=1/(np.exp(2*np.pi*1j*(Qx+Qv))-1)*(f1010v-g1010v)[:k_bpmac_v]
            g1010v[k_bpmac_v:]=1/(1-np.exp(-2*np.pi*1j*(Qx+Qv)))*(f1010v-g1010v)[k_bpmac_v:]
    
            f1001x=np.exp(1j*(psih-psix))*f1001h
            f1001x=f1001x-rh*np.exp(-1j*(psih+psix))/rch*np.conjugate(f1010h)
            f1001x=f1001x-2j*sin(np.pi*dh)*np.exp(1j*(Psih-Psix))*g1001h
            f1001x=f1001x-2j*sin(np.pi*dh)*np.exp(-1j*(Psih+Psix))/rch*np.conjugate(g1010h)
            f1001x=1/math.sqrt(1-rh**2)*sin(np.pi*(Qh-Qy))/sin(np.pi*(Qx-Qy))*f1001x
    
            f1010x=np.exp(1j*(psih-psix))*f1010h
            f1010x=f1010x-rh*np.exp(-1j*(psih+psix))*rch*np.conjugate(f1001h)
            f1010x=f1010x-2j*sin(np.pi*dh)*np.exp(1j*(Psih-Psix))*g1010h
            f1010x=f1010x-2j*sin(np.pi*dh)*np.exp(-1j*(Psih+Psix))*rch*np.conjugate(g1001h)
            f1010x=1/math.sqrt(1-rh**2)*sin(np.pi*(Qh+Qy))/sin(np.pi*(Qx+Qy))*f1010x
    
            f1001y=np.exp(-1j*(psiv-psiy))*f1001v
            f1001y=f1001y+rv*np.exp(1j*(psiv+psiy))/rcv*f1010v
            f1001y=f1001y+2j*sin(np.pi*dv)*np.exp(-1j*(Psiv-Psiy))*g1001v
            f1001y=f1001y-2j*sin(np.pi*dv)*np.exp(1j*(Psiv+Psiy))/rcv*g1010v
            f1001y=1/math.sqrt(1-rv**2)*sin(np.pi*(Qx-Qv))/sin(np.pi*(Qx-Qy))*f1001y
    
            f1010y=np.exp(1j*(psiv-psiy))*f1010v
            f1010y=f1010y+rv*np.exp(-1j*(psiv+psiy))*rcv*f1001v
            f1010y=f1010y-2j*sin(np.pi*dv)*np.exp(1j*(Psiv-Psiy))*g1010v
            f1010y=f1010y+2j*sin(np.pi*dv)*np.exp(-1j*(Psiv+Psiy))*rcv*g1001v
            f1010y=1/math.sqrt(1-rv**2)*sin(np.pi*(Qx+Qv))/sin(np.pi*(Qx+Qy))*f1010y
    
            #-- For B2, must be double checked
            if bd == -1:
                f1001x=-np.conjugate(f1001x)
                f1001y=-np.conjugate(f1001y)
                f1010x=-np.conjugate(f1010x)
                f1010y=-np.conjugate(f1010y)
    
            #-- Separate to amplitudes and phases, amplitudes averaged to cancel math.sqrt(betv/beth) and math.sqrt(beth/betv)
            for k in range(len(bpm)):
                f1001Abs[k][i] =math.sqrt(abs(f1001x[k]*f1001y[k]))
                f1010Abs[k][i] =math.sqrt(abs(f1010x[k]*f1010y[k]))
                f1001xArg[k][i]=np.angle(f1001x[k])%(2*np.pi)
                f1001yArg[k][i]=np.angle(f1001y[k])%(2*np.pi)
                f1010xArg[k][i]=np.angle(f1010x[k])%(2*np.pi)
                f1010yArg[k][i]=np.angle(f1010y[k])%(2*np.pi)
    
        #-- Output
        fwqw={}
        goodbpm=[]
        for k in range(len(bpm)):
    
            #-- Bad BPM flag based on phase
            badbpm=0
            f1001xArgAve = phase.calc_phase_mean(f1001xArg[k],2*np.pi)
            f1001yArgAve = phase.calc_phase_mean(f1001yArg[k],2*np.pi)
            f1010xArgAve = phase.calc_phase_mean(f1010xArg[k],2*np.pi)
            f1010yArgAve = phase.calc_phase_mean(f1010yArg[k],2*np.pi)
            #This seems to be to conservative or somethings...
            if min(abs(f1001xArgAve-f1001yArgAve),2*np.pi-abs(f1001xArgAve-f1001yArgAve))>np.pi/2: badbpm=1
            if min(abs(f1010xArgAve-f1010yArgAve),2*np.pi-abs(f1010xArgAve-f1010yArgAve))>np.pi/2: badbpm=1
            
            
            #-- Output
	    badbpm=0
            if badbpm==0:
                f1001AbsAve = np.mean(f1001Abs[k])
                f1010AbsAve = np.mean(f1010Abs[k])
                f1001ArgAve = phase.calc_phase_mean(np.append(f1001xArg[k],f1001yArg[k]),2*np.pi)
                f1010ArgAve = phase.calc_phase_mean(np.append(f1010xArg[k],f1010yArg[k]),2*np.pi)
                f1001Ave = f1001AbsAve*np.exp(1j*f1001ArgAve)
                f1010Ave = f1010AbsAve*np.exp(1j*f1010ArgAve)
                f1001AbsStd = math.sqrt(np.mean((f1001Abs[k]-f1001AbsAve)**2))
                f1010AbsStd = math.sqrt(np.mean((f1010Abs[k]-f1010AbsAve)**2))
                f1001ArgStd = phase.calc_phase_std(np.append(f1001xArg[k],f1001yArg[k]),2*np.pi)
                f1010ArgStd = phase.calc_phase_std(np.append(f1010xArg[k],f1010yArg[k]),2*np.pi)
                fwqw[bpm[k][1]] = [[f1001Ave          ,f1001AbsStd       ,f1010Ave          ,f1010AbsStd       ],
                                 [f1001ArgAve/(2*np.pi),f1001ArgStd/(2*np.pi),f1010ArgAve/(2*np.pi),f1010ArgStd/(2*np.pi)]]  #-- Phases renormalized to [0,1)
                goodbpm.append(bpm[k])
                
    #-- Global parameters not implemented yet
        
        fqwList.append(fwqw)
        
    
    fwqw = copy.deepcopy(fqwList[0])
    for key in fwqw:
        for a in range(1, len(fqwList)):
            tmp = fqwList[a]
            fwqw[key][0][0] = fwqw[key][0][0] + tmp[key][0][0]
            fwqw[key][0][1] = fwqw[key][0][1] + tmp[key][0][1]
            fwqw[key][0][2] = fwqw[key][0][2] + tmp[key][0][2]
            fwqw[key][0][3] = fwqw[key][0][3] + tmp[key][0][3]
            if(key is 'BPMWB.4R5.B1'):
                print fwqw[key][1]
        fwqw[key][0][0]=fwqw[key][0][0]/len(fqwList)
        fwqw[key][0][1]=fwqw[key][0][1]/len(fqwList)
        fwqw[key][0][2]=fwqw[key][0][2]/len(fqwList)
        fwqw[key][0][3]=fwqw[key][0][3]/len(fqwList)
    fwqw['Global']=['"null"','"null"']        
    return [fwqw,goodbpm]
def get_free_phase_eq(MADTwiss, Files, Qd, Q, psid_ac2bpmac, plane, bd, op, Qmdl, acdipole, important_pairs):


# 
#     print "\33[38;2;255;200;0m"
#     print "         /\\                     "
#     print "        //\\\\                   "
#     print "       //  \\\\                  "
#     print "      // || \\\\                 "
#     print "     //  ||  \\\\                "
#     print "    //   ||   \\\\               "
#     print "   //    ||    \\\\              "
#     print "  //            \\\\           "
#     print " //      ()      \\\\           "
#     print "//________________\\\\            "
#     print "--------------------               "
#     print "                               "
#     print "INFO: using changed code for ac compensation\n DO NOT TRUST THIS CODE\33[0m"

    print "Compensating {3:s} effect for plane {2:s}. Q = {0:f}, Qd = {1:f}".format(Q, Qd, plane, acdipole)

    #-- Select common BPMs
    bpm = utils.bpm.model_intersect(utils.bpm.intersect(Files), MADTwiss)
    bpm = [(b[0], str.upper(b[1])) for b in bpm]

    #-- Last BPM on the same turn to fix the phase shift by Q for exp data of LHC
    
    if op == "1":
        print "correcting phase jump"
        if 'MOH_3' in MADTwiss.NAME:
            print "--> for JPARC"
            s_lastbpm = MADTwiss.S[MADTwiss.indx['MOH_3']]
        else:
            print "--> for LHC"
            if bd == 1: s_lastbpm=MADTwiss.S[MADTwiss.indx['BPMSW.1L2.B1']]
            if bd == -1: s_lastbpm=MADTwiss.S[MADTwiss.indx['BPMSW.1L8.B2']]
    else:
        print "phase jump will not be corrected"

    #-- Determine the position of the AC dipole BPM
    bpmac1 = psid_ac2bpmac.keys()[0]
    bpmac2 = psid_ac2bpmac.keys()[1]
    
    try:
        k_bpmac = list(zip(*bpm)[1]).index(bpmac1)
        bpmac = bpmac1
    except:
        try:
            k_bpmac = list(zip(*bpm)[1]).index(bpmac2)
            bpmac = bpmac2
        except:
            print >> sys.stderr,'WARN: BPMs next to AC dipoles missing. AC dipole effects not calculated for '+plane+' with eqs !'
            return [{}, 0.0, []]

    #-- Model phase advances
    if plane=='H': psimdl=np.array([MADTwiss.MUX[MADTwiss.indx[b[1]]] for b in bpm])
    if plane=='V': psimdl=np.array([MADTwiss.MUY[MADTwiss.indx[b[1]]] for b in bpm])
    
    # <<<<<<<<<< ICH
    psiijmdl = [None] * 10
    psiijall = []


    for which_psi in range(1,11):
        psiijmdl[which_psi-1] = (np.append(psimdl[which_psi:], psimdl[:which_psi] + Qmdl) - psimdl) % 1
        psiijall.append(np.zeros((len(bpm), len(Files))))

    #-- Global parameters of the driven motion
    r=sin(PI * (Qd - Q)) / sin(PI * (Qd + Q))

    #-- Loop for files, psid, Psi, Psid are w.r.t the AC dipole
    
    psi_important = []  
    if important_pairs is not None:     
        for first_bpm in important_pairs:
            first_i = -1
            for i_ in range(len(bpm)):
                if bpm[i_][1] == first_bpm:
                    first_i = i_
            if first_i != -1:
                
                for second_bpm in important_pairs[first_bpm]:
                    
                    second_i = -1
                    for i_ in range(len(bpm)):
                        if bpm[i_][1] == second_bpm:
                            second_i = i_
                    if second_i != -1:
                        psi_important.append([first_bpm, first_i, second_bpm, second_i, []])
    for i in range(len(Files)):
        psid = []
        if plane == 'H':
            psid = bd * TWOPI * np.array([Files[i].MUX[Files[i].indx[b[1]]] for b in bpm])  #-- bd flips B2 phase to B1 direction
        if plane == 'V':
            psid = bd * TWOPI * np.array([Files[i].MUY[Files[i].indx[b[1]]] for b in bpm])  #-- bd flips B2 phase to B1 direction
        for k in range(len(bpm)):
            try:
                if bpm[k][0] > s_lastbpm: psid[k] += TWOPI * Qd  #-- To fix the phase shift by Q
            except: pass
        psid = psid - (psid[k_bpmac] - psid_ac2bpmac[bpmac])  # OK, untill here, it is Psi(s, s_ac)
        Psid=psid + PI * Qd
        Psid[k_bpmac:]=Psid[k_bpmac:]-TWOPI * Qd
        
        gamma = Psid*2
        alpha = psid + PI * Qd
        alpha[k_bpmac:] = alpha[k_bpmac:] + TWOPI * (Q - Qd) + kEPSILON
        
        Psi = np.arctan((1 - r) / (1 + r) * np.tan(Psid)) % PI  # Ryoichi
        Psi_a = np.arctan((1 + r * np.sin(alpha - gamma) / np.sin(alpha)) / (1 + r * np.cos(alpha - gamma)/np.cos(alpha)))
        for k in range(len(bpm)):
            if Psid[k] % TWOPI > PI: Psi[k] = Psi[k] + PI
        psi = Psi - Psi[0]
        psi[k_bpmac:] = psi[k_bpmac:] + TWOPI * Q
        
        # <<<<<<<<<< ICH
        psiij = [None] * 10
        for j in range(1, 11):
            psiij[j-1] = (np.append(psi[j:], psi[:j] + TWOPI * Q) - psi)/ TWOPI
        for k in range(len(bpm)):
            # <<<<<<<<<< ICH
            for j in range(0, 10):
                psiijall[j][k][i] = psiij[j][k]
                
        for fbpm, fi, sbpm, si, _list in psi_important:
            _list.append((psi[si] - psi[fi])/TWOPI)
                    
                
            
    #-- Output
   
    result={}
    muave=0.0  #-- mu is the same as psi but w/o mod
    for k in range(len(bpm)):
        # <<<<<<<<<< ICH
        psiijave = [None] * 10
        psiijstd = [None] * 10
        bnj = [None] * 11
        
        for j in range(0,11):
            bnj[j] = str.upper(bpm[(k + j) % len(bpm)][1])
        
        for j in range(0,10):
            psiijave[j] = phase.calc_phase_mean(psiijall[j][k],1)
            psiijstd[j] = phase.calc_phase_std(psiijall[j][k],1)
            result["".join([plane, bnj[0], bnj[j + 1]])] = [psiijave[j],psiijstd[j],psiijmdl[j][k]]
            
            
   
            
        muave += psiijave[0]
        try:    result[bpm[k][1]]=[psiijave[0],psiijstd[0],psiijave[1],psiijstd[1],psiijmdl[0][k],psiijmdl[1][k],bpm[k+1][1]]
        except: result[bpm[k][1]]=[psiijave[0],psiijstd[0],psiijave[1],psiijstd[1],psiijmdl[0][k],psiijmdl[1][k],bpm[0][1]]    #-- The last BPM
        
    
    for fbpm, fi, sbpm, si, _list in psi_important:
        result["".join([plane, fbpm, sbpm])] = [
            phase.calc_phase_mean(_list,1),
            phase.calc_phase_std(_list,1),
            0]
        
    return result, muave, bpm
def get_free_phase_total_eq(MADTwiss,Files,Qd,Q,psid_ac2bpmac,plane,bd,op):

    #-- Select common BPMs
    bpm=utils.bpm.model_intersect(utils.bpm.intersect(Files), MADTwiss)
    bpm=[(b[0],str.upper(b[1])) for b in bpm]

    #-- Last BPM on the same turn to fix the phase shift by Q for exp data of LHC
    if op == "1":
        if bd== 1: s_lastbpm=MADTwiss.S[MADTwiss.indx['BPMSW.1L2.B1']]
        if bd==-1: s_lastbpm=MADTwiss.S[MADTwiss.indx['BPMSW.1L8.B2']]
    else:
        print "LHC phase will not be corrected [total phase]"
    #-- Determine the BPM closest to the AC dipole and its position
    
    # WHY does this code exist?
#     for b in psid_ac2bpmac.keys():
#         if '5L4' in b: bpmac1=b
#         if '6L4' in b: bpmac2=b
    bpmac1 = psid_ac2bpmac.keys()[0]
    bpmac2 = psid_ac2bpmac.keys()[1]
    try:
        k_bpmac=list(zip(*bpm)[1]).index(bpmac1)
        bpmac=bpmac1
    except:
        try:
            k_bpmac=list(zip(*bpm)[1]).index(bpmac2)
            bpmac=bpmac2
        except:
            return [{},[]]

    # -- Model phase advances
    if plane == 'H':
        psimdl = np.array([(MADTwiss.MUX[MADTwiss.indx[b[1]]]-MADTwiss.MUX[MADTwiss.indx[bpm[0][1]]])%1 for b in bpm])
    if plane == 'V':
        psimdl=np.array([(MADTwiss.MUY[MADTwiss.indx[b[1]]]-MADTwiss.MUY[MADTwiss.indx[bpm[0][1]]])%1 for b in bpm])

    # -- Global parameters of the driven motion
    r = sin(np.pi * (Qd - Q)) / sin(np.pi * (Qd + Q))

    # -- Loop for files, psid, Psi, Psid are w.r.t the AC dipole
    psiall=np.zeros((len(bpm), len(Files)))
    for i in range(len(Files)):
        if plane == 'H':
            psid = bd * 2 * np.pi * np.array([Files[i].MUX[Files[i].indx[b[1]]] for b in bpm])  #-- bd flips B2 phase to B1 direction
        if plane=='V': psid=bd*2*np.pi*np.array([Files[i].MUY[Files[i].indx[b[1]]] for b in bpm])  #-- bd flips B2 phase to B1 direction
        for k in range(len(bpm)):
            try:
                if bpm[k][0]>s_lastbpm: psid[k]+=2*np.pi*Qd  #-- To fix the phase shift by Q
            except: pass
        psid=psid-(psid[k_bpmac]-psid_ac2bpmac[bpmac])
        Psid=psid+np.pi*Qd
        Psid[k_bpmac:]=Psid[k_bpmac:]-2*np.pi*Qd
        Psi=np.arctan((1-r)/(1+r)*np.tan(Psid))%np.pi
        for k in range(len(bpm)):
            if Psid[k]%(2*np.pi)>np.pi: Psi[k]=Psi[k]+np.pi
        psi=Psi-Psi[0]
        psi[k_bpmac:]=psi[k_bpmac:]+2*np.pi*Q
        for k in range(len(bpm)): psiall[k][i]=psi[k]/(2*np.pi)  #-- phase range back to [0,1)

    #-- Output
    result={}
    for k in range(len(bpm)):
        psiave = phase.calc_phase_mean(psiall[k],1)
        psistd = phase.calc_phase_std(psiall[k],1)
        result[bpm[k][1]]=[psiave,psistd,psimdl[k],bpm[0][1]]

    return [result,bpm]
Exemplo n.º 4
0
def GetCoupling2(MADTwiss, list_zero_dpp_x, list_zero_dpp_y, tune_x, tune_y,
                 phasex, phasey, beam_direction, accel, outputpath):
    """Calculate coupling and phase with 2-BPM method for all BPMs and overall
    INPUT
     MADTwiss        - twiss instance of model from MAD 
     list_zero_dpp_x - list with twiss objects for horizontal data
     list_zero_dpp_y - list with twiss objects for vertical data
     tune_x          - horizontal tune (use natural/free tunes!)
     tune_y          - vertical tune (use natural/free tunes!)
     phasex          - horizontal phase (usage with phase.py in algorithms)
     phasey          - vertical phase (usage with phase.py in algorithms)
     beam_direction  - direction of beam, LHCB1: 1, LHCB2: -1
     accel           - accelerator (LHCB1, LHCB2, LHCB4(?), SPS, RHIC,TEVATRON)
     outputpath      - directory which contains the Drive.inp file to determine operation point
    OUTPUT
     fwqw            - library with BPMs and corresponding results
     dbpms           - list of BPMs with correct phase
    """

    ### Prepare BPM lists ###

    # Check linx/liny files, if it's OK it is confirmed that ListofZeroDPPX[i] and ListofZeroDPPY[i]
    # come from the same (simultaneous) measurement. It might be redundant check.
    if len(list_zero_dpp_x) != len(list_zero_dpp_y):
        print >> sys.stderr, 'Leaving GetCoupling as linx and liny files seem not correctly paired...'
        dum0 = {"Global": [0.0, 0.0]}
        dum1 = []
        return [dum0, dum1]
    # Determine intersection of BPM-lists between measurement and model, create list dbpms
    XplusY = list_zero_dpp_x + list_zero_dpp_y
    dbpms = Utilities.bpm.intersect(XplusY)
    dbpms = Utilities.bpm.model_intersect(dbpms, MADTwiss)

    ### Calculate fw and qw, exclude BPMs having wrong phases ###

    # Initialize dictionary of BPMs with results
    fwqw = {}
    # Initialize dictionary of BPMs with results for old method
    f_old_out = {}
    # Initialize list of BPMs with correct phases
    dbpmt = []
    # Count number of BPM-pairs in intersection of model and measurement
    Numbpmpairs = len(dbpms) - 1
    # Loop through BPM-pairs
    for i in range(Numbpmpairs):
        # Get BPM names
        bn1 = str.upper(dbpms[i][1])
        bn2 = str.upper(dbpms[i + 1][1])
        delx = phasex[bn1][0] - 0.25  # Missprint in the coupling note
        dely = phasey[bn1][0] - 0.25

        # Initialize result-lists (coupling, error on coupling and phases)
        f1001ij = []
        f1010ij = []
        std_f1001ij = []
        std_f1010ij = []
        q1js = []
        q2js = []
        q1jd = []
        q2jd = []
        # Initialize as not bad BPM
        badbpm = 0
        # Loop through files to analyze
        for j in range(0, len(list_zero_dpp_x)):
            # Get twiss instance for current BPM and file
            tw_x = list_zero_dpp_x[j]
            tw_y = list_zero_dpp_y[j]
            # Get main amplitude
            [ampx_1,
             ampy_1] = [tw_x.AMPX[tw_x.indx[bn1]], tw_y.AMPY[tw_y.indx[bn1]]]
            [ampx_2,
             ampy_2] = [tw_x.AMPX[tw_x.indx[bn2]], tw_y.AMPY[tw_y.indx[bn2]]]
            # Exclude BPM if no main line was found
            if ampx_1 == 0 or ampy_1 == 0 or ampx_2 == 0 or ampy_2 == 0:
                badbpm = 1
                ampx_1 = 1  # Dummy value, badbpm variable makes sure the BPM is ignored
                ampy_1 = 1  # Dummy value, badbpm variable makes sure the BPM is ignored
                ampx_2 = 1  # Dummy value, badbpm variable makes sure the BPM is ignored
                ampy_2 = 1  # Dummy value, badbpm variable makes sure the BPM is ignored
            # Get coupled amplitude ratios
            [amp01_1, amp10_1
             ] = [tw_x.AMP01[tw_x.indx[bn1]], tw_y.AMP10[tw_y.indx[bn1]]]
            [amp01_2, amp10_2
             ] = [tw_x.AMP01[tw_x.indx[bn2]], tw_y.AMP10[tw_y.indx[bn2]]]
            # Replace secondary lines with amplitude infinity or 0 by noise average
            try:
                if amp01_1 == float("inf") or amp01_1 == 0:
                    amp01_1 = tw_x.AVG_NOISE[tw_x.indx[bn1]] / ampx_1
                if amp10_1 == float("inf") or amp10_1 == 0:
                    amp10_1 = tw_y.AVG_NOISE[tw_y.indx[bn1]] / ampy_1
                if amp01_2 == float("inf") or amp01_2 == 0:
                    amp01_2 = tw_x.AVG_NOISE[tw_x.indx[bn1]] / ampx_2
                if amp10_2 == float("inf") or amp10_2 == 0:
                    amp10_2 = tw_y.AVG_NOISE[tw_y.indx[bn1]] / ampy_2
            except AttributeError:
                print "AVG_NOISE column not found, cannot use noise floor."

            # Call routine in helper.py to get secondary lines for 2-BPM method
            [SA0p1ij, phi0p1ij
             ] = helper.ComplexSecondaryLine(delx, amp01_1, amp01_2,
                                             tw_x.PHASE01[tw_x.indx[bn1]],
                                             tw_x.PHASE01[tw_x.indx[bn2]])
            [SA0m1ij, phi0m1ij
             ] = helper.ComplexSecondaryLine(delx, amp01_1, amp01_2,
                                             -tw_x.PHASE01[tw_x.indx[bn1]],
                                             -tw_x.PHASE01[tw_x.indx[bn2]])
            [TBp10ij, phip10ij
             ] = helper.ComplexSecondaryLine(dely, amp10_1, amp10_2,
                                             tw_y.PHASE10[tw_y.indx[bn1]],
                                             tw_y.PHASE10[tw_y.indx[bn2]])
            [TBm10ij, phim10ij
             ] = helper.ComplexSecondaryLine(dely, amp10_1, amp10_2,
                                             -tw_y.PHASE10[tw_y.indx[bn1]],
                                             -tw_y.PHASE10[tw_y.indx[bn2]])

            # Get noise standard deviation and propagate to coupled amplitude ratio
            std_amp01_1 = tw_x.NOISE[tw_x.indx[bn1]] / ampx_1 * math.sqrt(
                1 + amp01_1**2)
            std_amp10_1 = tw_y.NOISE[tw_y.indx[bn1]] / ampy_1 * math.sqrt(
                1 + amp10_1**2)
            std_amp01_2 = tw_x.NOISE[tw_x.indx[bn2]] / ampx_2 * math.sqrt(
                1 + amp01_2**2)
            std_amp10_2 = tw_y.NOISE[tw_y.indx[bn2]] / ampy_2 * math.sqrt(
                1 + amp10_2**2)
            # Propagate to 2-BPM coupled amplitude ratio using a separate routine in helper.py
            std_SA0p1ij = helper.ComplexSecondaryLineSTD(
                delx, amp01_1, amp01_2, tw_x.PHASE01[tw_x.indx[bn1]],
                tw_x.PHASE01[tw_x.indx[bn2]], std_amp01_1, std_amp01_2)
            std_SA0m1ij = helper.ComplexSecondaryLineSTD(
                delx, amp01_1, amp01_2, -tw_x.PHASE01[tw_x.indx[bn1]],
                -tw_x.PHASE01[tw_x.indx[bn2]], std_amp01_1, std_amp01_2)
            std_TBp10ij = helper.ComplexSecondaryLineSTD(
                dely, amp10_1, amp10_2, tw_y.PHASE10[tw_y.indx[bn1]],
                tw_y.PHASE10[tw_y.indx[bn2]], std_amp10_1, std_amp10_2)
            std_TBm10ij = helper.ComplexSecondaryLineSTD(
                dely, amp10_1, amp10_2, -tw_y.PHASE10[tw_y.indx[bn1]],
                -tw_y.PHASE10[tw_y.indx[bn2]], std_amp10_1, std_amp10_2)

            # Append results for the coupling parameters
            f1001ij.append(
                0.5 * math.sqrt(TBp10ij * SA0p1ij / 2.0 / 2.0)
            )  # division by 2 for each ratio as the scale of the #
            f1010ij.append(
                0.5 * math.sqrt(TBm10ij * SA0m1ij / 2.0 / 2.0)
            )  # main lines is 2 (also see appendix of the note)  #
            # Propagate error to f1001 and f1010 if possible (no division by 0)
            if TBp10ij == 0 or SA0p1ij == 0:
                std_f1001ij.append(float("nan"))
            else:
                std_f1001ij.append(0.25 * math.sqrt(4.0 / TBp10ij / SA0p1ij) *
                                   math.sqrt((std_TBp10ij * SA0p1ij / 4)**2 +
                                             (TBp10ij * std_SA0p1ij / 4)**2))
            if TBm10ij == 0 or SA0m1ij == 0:
                std_f1010ij.append(float("nan"))
            else:
                std_f1010ij.append(0.25 * math.sqrt(4.0 / TBm10ij / SA0m1ij) *
                                   math.sqrt((std_TBm10ij * SA0m1ij / 4)**2 +
                                             (TBm10ij * std_SA0m1ij / 4)**2))

            if beam_direction == 1:
                q1jd.append((phi0p1ij - tw_y.MUY[tw_y.indx[bn1]] + 0.25) %
                            1.0)  # note that phases are in units of 2pi
                q2jd.append(
                    (-phip10ij + tw_x.MUX[tw_x.indx[bn1]] - 0.25) % 1.0)
            elif beam_direction == -1:
                q1jd.append((phi0p1ij - tw_y.MUY[tw_y.indx[bn1]] + 0.25) %
                            1.0)  # note that phases are in units of 2pi
                q2jd.append(-(-phip10ij + tw_x.MUX[tw_x.indx[bn1]] - 0.25) %
                            1.0)

            # This sign change in the real part is to comply with MAD output
            q1jd[j] = (0.5 - q1jd[j]) % 1.0
            q2jd[j] = (0.5 - q2jd[j]) % 1.0

            if beam_direction == 1:
                q1js.append((phi0m1ij + tw_y.MUY[tw_y.indx[bn1]] + 0.25) %
                            1.0)  # note that phases are in units of 2pi
                q2js.append((phim10ij + tw_x.MUX[tw_x.indx[bn1]] + 0.25) % 1.0)
            if beam_direction == -1:
                q1js.append((phi0m1ij + tw_y.MUY[tw_y.indx[bn1]] + 0.25) %
                            1.0)  # note that phases are in units of 2pi
                q2js.append(-(phim10ij + tw_x.MUX[tw_x.indx[bn1]] + 0.25) %
                            1.0)
            # This sign change in the real part is to comply with MAD output
            q1js[j] = (0.5 - q1js[j]) % 1.0
            q2js[j] = (0.5 - q2js[j]) % 1.0

        q1jd = np.array(q1jd)
        q2jd = np.array(q2jd)
        q1d = phase.calc_phase_mean(q1jd, 1.0)
        q2d = phase.calc_phase_mean(q2jd, 1.0)

        q1js = np.array(q1js)
        q2js = np.array(q2js)
        q1s = phase.calc_phase_mean(q1js, 1.0)
        q2s = phase.calc_phase_mean(q2js, 1.0)

        # Take SPS and RHIC out of the badbpm procedure (badbpm stays 0 as initialized) and set phases
        if (accel == "SPS" or accel == "RHIC"):
            q1010i = q1d
            q1010i = q1s

        # Check phase and set badbpm for wrong phase (only for other accels than SPS and RHIC)
        elif min(abs(q1d - q2d), 1.0 - abs(q1d - q2d)) > 0.25 or min(
                abs(q1s - q2s), 1.0 - abs(q1s - q2s)) > 0.25:
            badbpm = 1

        # If accel is SPS or RHIC or no no wrong phase was detected, process results
        if badbpm == 0:
            # Cast coupling parameters and errors as np.arrays for later calculations
            f1001ij = np.array(f1001ij)
            f1010ij = np.array(f1010ij)
            std_f1001ij = np.array(std_f1001ij)
            std_f1010ij = np.array(std_f1010ij)

            # Old cminus method: averaging abs values
            if beam_direction == 1:
                f_old_out[bn1] = np.average(abs(f1001ij),
                                            weights=1 / std_f1001ij**2)
            elif beam_direction == -1:
                f_old_out[bn1] = np.average(abs(f1010ij),
                                            weights=1 / std_f1010ij**2)

            # Use variance-weighted average to determine f and its std
            f1001i = np.average(f1001ij, weights=1 / std_f1001ij**2)
            f1010i = np.average(f1010ij, weights=1 / std_f1010ij**2)
            # Set std of f1001 and f1010 by calculating the std of the weighted average
            f1001istd = np.sqrt(1 / sum(1 / std_f1001ij**2))
            f1010istd = np.sqrt(1 / sum(1 / std_f1010ij**2))

            # Use routines in phase.py to get mean and std of the phase terms q1001 and q1010
            q1001i = phase.calc_phase_mean(np.array([q1d, q2d]), 1.0)
            q1010i = phase.calc_phase_mean(np.array([q1s, q2s]), 1.0)
            q1001istd = phase.calc_phase_std(np.append(q1jd, q2jd), 1.0)
            q1010istd = phase.calc_phase_std(np.append(q1js, q2js), 1.0)
            # Calculate complex coupling terms using phases from above
            f1001i = f1001i * complex(np.cos(2.0 * np.pi * q1001i),
                                      np.sin(2.0 * np.pi * q1001i))
            f1010i = f1010i * complex(np.cos(2.0 * np.pi * q1010i),
                                      np.sin(2.0 * np.pi * q1010i))
            # Add BPM to list of BPMs with correct phase
            dbpmt.append([dbpms[i][0], dbpms[i][1]])

            # Save results to BPM-results dictionary, sorted depending on beam_direction
            if beam_direction == 1:
                fwqw[bn1] = [[f1001i, f1001istd, f1010i, f1010istd],
                             [q1001i, q1001istd, q1010i, q1010istd]]
            elif beam_direction == -1:
                fwqw[bn1] = [[f1010i, f1010istd, f1001i, f1001istd],
                             [q1010i, q1010istd, q1001i, q1001istd]]

    # Count number of skipped BPMs because of wrong phase
    Badbpms = len(dbpms) - len(dbpmt)
    # Rename list of BPMs with correct phase
    dbpms = dbpmt

    # Compute global values for coupling, error and phase
    # Initialize coupling term f
    f_new = complex(0, 0)
    # Initialize denominator for weighted averaging
    denom = 0
    # Loop through BPMs with correct phase
    for i in range(0, len(dbpms) - 1):
        # Get BPM-names
        bn1 = str.upper(dbpms[i][1])
        bn2 = str.upper(dbpms[i + 1][1])
        mux = MADTwiss.MUX[MADTwiss.indx[bn1]]
        muy = MADTwiss.MUY[MADTwiss.indx[bn2]]
        f_new += fwqw[bn2][0][0] * np.exp(
            complex(0, 1) * 2 * np.pi *
            (mux -
             muy)) / fwqw[bn2][0][1]**2  # Variance-weighted average for BPMs
        denom += 1 / fwqw[bn2][0][1]**2  # denominator for weighted average

    N = len(dbpms)
    f_new_std = np.sqrt(1 / denom)
    CG_new_abs = 4 * abs(tune_x - tune_y) * abs(f_new) / denom
    CG_new_abs_std = 4 * abs(tune_x - tune_y) * abs(f_new_std)
    CG_new_phase = np.angle(f_new)

    print('NewCMINUS: {0} +/- {1}'.format(CG_new_abs, CG_new_abs_std))
    print('Skipped BPMs: {0} (badbpm) of {1}'.format(Badbpms, Numbpmpairs))

    # Old formula
    # Initialize global values coupling CG and phse QG
    CG = 0.0
    QG = 0.0
    for i in range(0, len(dbpms) - 1):
        bn1 = str.upper(dbpms[i][1])
        CG += abs(f_old_out[bn1])
        # For more than one file, this goes wrong, loops are mixed up for the phase calculation!
        tw_x = list_zero_dpp_x[0]
        tw_y = list_zero_dpp_y[0]
        QG += fwqw[bn1][1][0] - (tw_x.MUX[tw_x.indx[bn1]] -
                                 tw_y.MUY[tw_y.indx[bn1]])

    if len(dbpms) == 0:
        print >> sys.stderr, 'Warning: There is no BPM to output linear coupling properly... leaving Getcoupling.'
        # Does this set a coupling without prefactor 4*(Qx-Qy) to global?
        fwqw['Global'] = [CG, QG]  #Quick fix Evian 2012
        return [fwqw, dbpms]
    else:
        CG_old = abs(4.0 * (tune_x - tune_y) * CG / len(dbpms))
    print 'OldCMINUS', CG_old
    fwqw['Global'] = [CG_new_abs, CG_new_phase, CG_new_abs_std]

    return [fwqw, dbpms]
Exemplo n.º 5
0
def get_free_phase_eq(MADTwiss, Files, Qd, Q, psid_ac2bpmac, plane, bd, op,
                      Qmdl):

    #-- Select common BPMs
    bpm = Utilities.bpm.model_intersect(Utilities.bpm.intersect(Files),
                                        MADTwiss)
    bpm = [(b[0], str.upper(b[1])) for b in bpm]

    #-- Last BPM on the same turn to fix the phase shift by Q for exp data of LHC
    if op == "1" and bd == 1:
        s_lastbpm = MADTwiss.S[MADTwiss.indx['BPMSW.1L2.B1']]
    if op == "1" and bd == -1:
        s_lastbpm = MADTwiss.S[MADTwiss.indx['BPMSW.1L8.B2']]

    #-- Determine the position of the AC dipole BPM
    for b in psid_ac2bpmac.keys():
        if '5L4' in b: bpmac1 = b
        if '6L4' in b: bpmac2 = b
    try:
        k_bpmac = list(zip(*bpm)[1]).index(bpmac1)
        bpmac = bpmac1
    except:
        try:
            k_bpmac = list(zip(*bpm)[1]).index(bpmac2)
            bpmac = bpmac2
        except:
            print >> sys.stderr, 'WARN: BPMs next to AC dipoles missing. AC dipole effects not calculated for ' + plane + ' with eqs !'
            return [{}, 0.0, []]

    #-- Model phase advances
    if plane == 'H':
        psimdl = np.array([MADTwiss.MUX[MADTwiss.indx[b[1]]] for b in bpm])
    if plane == 'V':
        psimdl = np.array([MADTwiss.MUY[MADTwiss.indx[b[1]]] for b in bpm])
    psi12mdl = (np.append(psimdl[1:], psimdl[0] + Qmdl) - psimdl) % 1
    psi13mdl = (np.append(psimdl[2:], psimdl[:2] + Qmdl) - psimdl) % 1
    psi14mdl = (np.append(psimdl[3:], psimdl[:3] + Qmdl) - psimdl) % 1
    psi15mdl = (np.append(psimdl[4:], psimdl[:4] + Qmdl) - psimdl) % 1
    psi16mdl = (np.append(psimdl[5:], psimdl[:5] + Qmdl) - psimdl) % 1
    psi17mdl = (np.append(psimdl[6:], psimdl[:6] + Qmdl) - psimdl) % 1
    psi18mdl = (np.append(psimdl[7:], psimdl[:7] + Qmdl) - psimdl) % 1
    psi19mdl = (np.append(psimdl[8:], psimdl[:8] + Qmdl) - psimdl) % 1
    psi110mdl = (np.append(psimdl[9:], psimdl[:9] + Qmdl) - psimdl) % 1
    psi111mdl = (np.append(psimdl[10:], psimdl[:10] + Qmdl) - psimdl) % 1

    #-- Global parameters of the driven motion
    r = sin(np.pi * (Qd - Q)) / sin(np.pi * (Qd + Q))

    #-- Loop for files, psid, Psi, Psid are w.r.t the AC dipole
    psi12all = np.zeros((len(bpm), len(Files)))
    psi13all = np.zeros((len(bpm), len(Files)))
    psi14all = np.zeros((len(bpm), len(Files)))
    psi15all = np.zeros((len(bpm), len(Files)))
    psi16all = np.zeros((len(bpm), len(Files)))
    psi17all = np.zeros((len(bpm), len(Files)))
    psi18all = np.zeros((len(bpm), len(Files)))
    psi19all = np.zeros((len(bpm), len(Files)))
    psi110all = np.zeros((len(bpm), len(Files)))
    psi111all = np.zeros((len(bpm), len(Files)))
    for i in range(len(Files)):
        if plane == 'H':
            psid = bd * 2 * np.pi * np.array(
                [Files[i].MUX[Files[i].indx[b[1]]]
                 for b in bpm])  #-- bd flips B2 phase to B1 direction
        if plane == 'V':
            psid = bd * 2 * np.pi * np.array(
                [Files[i].MUY[Files[i].indx[b[1]]]
                 for b in bpm])  #-- bd flips B2 phase to B1 direction
        for k in range(len(bpm)):
            try:
                if bpm[k][0] > s_lastbpm:
                    psid[k] += 2 * np.pi * Qd  #-- To fix the phase shift by Q
            except:
                pass
        psid = psid - (psid[k_bpmac] - psid_ac2bpmac[bpmac])
        Psid = psid + np.pi * Qd
        Psid[k_bpmac:] = Psid[k_bpmac:] - 2 * np.pi * Qd
        Psi = np.arctan((1 - r) / (1 + r) * np.tan(Psid)) % np.pi
        for k in range(len(bpm)):
            if Psid[k] % (2 * np.pi) > np.pi: Psi[k] = Psi[k] + np.pi
        psi = Psi - Psi[0]
        psi[k_bpmac:] = psi[k_bpmac:] + 2 * np.pi * Q
        psi12 = (np.append(psi[1:], psi[0] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        #psi12=(np.append(psi[1:],psi[0])-psi)/(2*np.pi)  #-- phase range back to [0,1)
        psi13 = (np.append(psi[2:], psi[:2] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        psi14 = (np.append(psi[3:], psi[:3] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        psi15 = (np.append(psi[4:], psi[:4] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        psi16 = (np.append(psi[5:], psi[:5] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        psi17 = (np.append(psi[6:], psi[:6] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        psi18 = (np.append(psi[7:], psi[:7] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        psi19 = (np.append(psi[8:], psi[:8] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        psi110 = (np.append(psi[9:], psi[:9] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        psi111 = (np.append(psi[10:], psi[:10] + 2 * np.pi * Q) - psi) / (
            2 * np.pi)  #-- phase range back to [0,1)
        for k in range(len(bpm)):
            psi12all[k][i] = psi12[k]
            psi13all[k][i] = psi13[k]
            psi14all[k][i] = psi14[k]
            psi15all[k][i] = psi15[k]
            psi16all[k][i] = psi16[k]
            psi17all[k][i] = psi17[k]
            psi18all[k][i] = psi18[k]
            psi19all[k][i] = psi19[k]
            psi110all[k][i] = psi110[k]
            psi111all[k][i] = psi111[k]

    #-- Output
    result = {}
    muave = 0.0  #-- mu is the same as psi but w/o mod
    for k in range(len(bpm)):
        psi12ave = phase.calc_phase_mean(psi12all[k], 1)
        psi12std = phase.calc_phase_std(psi12all[k], 1)
        psi13ave = phase.calc_phase_mean(psi13all[k], 1)
        psi13std = phase.calc_phase_std(psi13all[k], 1)
        psi14ave = phase.calc_phase_mean(psi14all[k], 1)
        psi14std = phase.calc_phase_std(psi14all[k], 1)
        psi15ave = phase.calc_phase_mean(psi15all[k], 1)
        psi15std = phase.calc_phase_std(psi15all[k], 1)
        psi16ave = phase.calc_phase_mean(psi16all[k], 1)
        psi16std = phase.calc_phase_std(psi16all[k], 1)
        psi17ave = phase.calc_phase_mean(psi17all[k], 1)
        psi17std = phase.calc_phase_std(psi17all[k], 1)
        psi18ave = phase.calc_phase_mean(psi18all[k], 1)
        psi18std = phase.calc_phase_std(psi18all[k], 1)
        psi19ave = phase.calc_phase_mean(psi19all[k], 1)
        psi19std = phase.calc_phase_std(psi19all[k], 1)
        psi110ave = phase.calc_phase_mean(psi110all[k], 1)
        psi110std = phase.calc_phase_std(psi110all[k], 1)
        psi111ave = phase.calc_phase_mean(psi111all[k], 1)
        psi111std = phase.calc_phase_std(psi111all[k], 1)
        muave = muave + psi12ave
        try:
            result[bpm[k][1]] = [
                psi12ave, psi12std, psi13ave, psi13std, psi12mdl[k],
                psi13mdl[k], bpm[k + 1][1]
            ]
        except:
            result[bpm[k][1]] = [
                psi12ave, psi12std, psi13ave, psi13std, psi12mdl[k],
                psi13mdl[k], bpm[0][1]
            ]  #-- The last BPM

        bn1 = str.upper(bpm[k % len(bpm)][1])
        bn2 = str.upper(bpm[(k + 1) % len(bpm)][1])
        bn3 = str.upper(bpm[(k + 2) % len(bpm)][1])
        bn4 = str.upper(bpm[(k + 3) % len(bpm)][1])
        bn5 = str.upper(bpm[(k + 4) % len(bpm)][1])
        bn6 = str.upper(bpm[(k + 5) % len(bpm)][1])
        bn7 = str.upper(bpm[(k + 6) % len(bpm)][1])
        bn8 = str.upper(bpm[(k + 7) % len(bpm)][1])
        bn9 = str.upper(bpm[(k + 8) % len(bpm)][1])
        bn10 = str.upper(bpm[(k + 9) % len(bpm)][1])
        bn11 = str.upper(bpm[(k + 10) % len(bpm)][1])

        if plane == 'H':
            result["".join(['H', bn1,
                            bn2])] = [psi12ave, psi12std, psi12mdl[k]]
            result["".join(['H', bn1,
                            bn3])] = [psi13ave, psi13std, psi13mdl[k]]
            result["".join(['H', bn1,
                            bn4])] = [psi14ave, psi14std, psi14mdl[k]]
            result["".join(['H', bn1,
                            bn5])] = [psi15ave, psi15std, psi15mdl[k]]
            result["".join(['H', bn1,
                            bn6])] = [psi16ave, psi16std, psi16mdl[k]]
            result["".join(['H', bn1,
                            bn7])] = [psi17ave, psi17std, psi17mdl[k]]
            result["".join(['H', bn1,
                            bn8])] = [psi18ave, psi18std, psi18mdl[k]]
            result["".join(['H', bn1,
                            bn9])] = [psi19ave, psi19std, psi19mdl[k]]
            result["".join(['H', bn1,
                            bn10])] = [psi110ave, psi110std, psi110mdl[k]]
            result["".join(['H', bn1,
                            bn11])] = [psi111ave, psi111std, psi111mdl[k]]
        elif plane == 'V':
            result["".join(['V', bn1,
                            bn2])] = [psi12ave, psi12std, psi12mdl[k]]
            result["".join(['V', bn1,
                            bn3])] = [psi13ave, psi13std, psi13mdl[k]]
            result["".join(['V', bn1,
                            bn4])] = [psi14ave, psi14std, psi14mdl[k]]
            result["".join(['V', bn1,
                            bn5])] = [psi15ave, psi15std, psi15mdl[k]]
            result["".join(['V', bn1,
                            bn6])] = [psi16ave, psi16std, psi16mdl[k]]
            result["".join(['V', bn1,
                            bn7])] = [psi17ave, psi17std, psi17mdl[k]]
            result["".join(['V', bn1,
                            bn8])] = [psi18ave, psi18std, psi18mdl[k]]
            result["".join(['V', bn1,
                            bn9])] = [psi19ave, psi19std, psi19mdl[k]]
            result["".join(['V', bn1,
                            bn10])] = [psi110ave, psi110std, psi110mdl[k]]
            result["".join(['V', bn1,
                            bn11])] = [psi111ave, psi111std, psi111mdl[k]]
    return [result, muave, bpm]
Exemplo n.º 6
0
def GetCoupling2(MADTwiss, list_zero_dpp_x, list_zero_dpp_y, tune_x, tune_y,
                 phasex, phasey, beam_direction, accel, outputpath):
    # check linx/liny files, if it's OK it is confirmed that ListofZeroDPPX[i] and ListofZeroDPPY[i]
    # come from the same (simultaneous) measurement. It might be redundant check.
    if len(list_zero_dpp_x) != len(list_zero_dpp_y):
        print >> sys.stderr, 'Leaving GetCoupling as linx and liny files seem not correctly paired...'
        dum0 = {"Global": [0.0, 0.0]}
        dum1 = []
        return [dum0, dum1]

    XplusY = list_zero_dpp_x + list_zero_dpp_y
    dbpms = Utilities.bpm.intersect(XplusY)
    dbpms = Utilities.bpm.model_intersect(dbpms, MADTwiss)

    # caculate fw and qw, exclude bpms having wrong phases
    fwqw = {}
    dbpmt = []
    countBadPhase = 0
    for i in range(0, len(dbpms) - 1):
        bn1 = str.upper(dbpms[i][1])
        bn2 = str.upper(dbpms[i + 1][1])

        delx = phasex[bn1][0] - 0.25  # Missprint in the coupling note
        dely = phasey[bn1][0] - 0.25

        f1001ij = []
        f1010ij = []
        q1js = []
        q2js = []
        q1jd = []
        q2jd = []
        badbpm = 0
        for j in range(0, len(list_zero_dpp_x)):
            tw_x = list_zero_dpp_x[j]
            tw_y = list_zero_dpp_y[j]
            [SA0p1ij, phi0p1ij] = helper.ComplexSecondaryLine(
                delx, tw_x.AMP01[tw_x.indx[bn1]], tw_x.AMP01[tw_x.indx[bn2]],
                tw_x.PHASE01[tw_x.indx[bn1]], tw_x.PHASE01[tw_x.indx[bn2]])
            [SA0m1ij, phi0m1ij] = helper.ComplexSecondaryLine(
                delx, tw_x.AMP01[tw_x.indx[bn1]], tw_x.AMP01[tw_x.indx[bn2]],
                -tw_x.PHASE01[tw_x.indx[bn1]], -tw_x.PHASE01[tw_x.indx[bn2]])
            [TBp10ij, phip10ij] = helper.ComplexSecondaryLine(
                dely, tw_y.AMP10[tw_y.indx[bn1]], tw_y.AMP10[tw_y.indx[bn2]],
                tw_y.PHASE10[tw_y.indx[bn1]], tw_y.PHASE10[tw_y.indx[bn2]])
            [TBm10ij, phim10ij] = helper.ComplexSecondaryLine(
                dely, tw_y.AMP10[tw_y.indx[bn1]], tw_y.AMP10[tw_y.indx[bn2]],
                -tw_y.PHASE10[tw_y.indx[bn1]], -tw_y.PHASE10[tw_y.indx[bn2]])

            #print SA0p1ij,phi0p1ij,SA0m1ij,phi0m1ij,TBp10ij,phip10ij,TBm10ij,phim10ij
            f1001ij.append(0.5 * math.sqrt(TBp10ij * SA0p1ij / 2.0 / 2.0))
            f1010ij.append(0.5 * math.sqrt(TBm10ij * SA0m1ij / 2.0 / 2.0))

            if beam_direction == 1:
                q1jd.append((phi0p1ij - tw_y.MUY[tw_y.indx[bn1]] + 0.25) %
                            1.0)  # note that phases are in units of 2pi
                q2jd.append(
                    (-phip10ij + tw_x.MUX[tw_x.indx[bn1]] - 0.25) % 1.0)
            elif beam_direction == -1:
                q1jd.append((phi0p1ij - tw_y.MUY[tw_y.indx[bn1]] + 0.25) %
                            1.0)  # note that phases are in units of 2pi
                q2jd.append(-(-phip10ij + tw_x.MUX[tw_x.indx[bn1]] - 0.25) %
                            1.0)
            #print q1,q2
            q1jd[j] = (
                0.5 - q1jd[j]
            ) % 1.0  # This sign change in the real part is to comply with MAD output
            q2jd[j] = (0.5 - q2jd[j]) % 1.0

            if beam_direction == 1:
                q1js.append((phi0m1ij + tw_y.MUY[tw_y.indx[bn1]] + 0.25) %
                            1.0)  # note that phases are in units of 2pi
                q2js.append((phim10ij + tw_x.MUX[tw_x.indx[bn1]] + 0.25) % 1.0)
            if beam_direction == -1:
                q1js.append((phi0m1ij + tw_y.MUY[tw_y.indx[bn1]] + 0.25) %
                            1.0)  # note that phases are in units of 2pi
                q2js.append(-(phim10ij + tw_x.MUX[tw_x.indx[bn1]] + 0.25) %
                            1.0)
            #print q1,q2
            q1js[j] = (
                0.5 - q1js[j]
            ) % 1.0  # This sign change in the real part is to comply with MAD output
            q2js[j] = (0.5 - q2js[j]) % 1.0

        q1jd = np.array(q1jd)
        q2jd = np.array(q2jd)
        q1d = phase.calc_phase_mean(q1jd, 1.0)
        q2d = phase.calc_phase_mean(q2jd, 1.0)

        q1js = np.array(q1js)
        q2js = np.array(q2js)
        q1s = phase.calc_phase_mean(q1js, 1.0)
        q2s = phase.calc_phase_mean(q2js, 1.0)

        if min(abs(q1d - q2d), 1.0 - abs(q1d - q2d)) > 0.25 or min(
                abs(q1s - q2s), 1.0 - abs(q1s - q2s)) > 0.25:
            badbpm = 1
            countBadPhase += 1

        if (accel == "SPS" or accel == "RHIC"):
            # No check for the SPS or RHIC
            badbpm = 0
            q1010i = q1d
            q1010i = q1s
            countBadPhase += 1

        if badbpm == 0:

            f1001ij = np.array(f1001ij)
            f1001i = np.average(f1001ij)
            f1001istd = math.sqrt(
                np.average(f1001ij * f1001ij) - (np.average(f1001ij))**2.0 +
                2.2e-16)
            f1010ij = np.array(f1010ij)
            f1010i = np.average(f1010ij)
            f1010istd = math.sqrt(
                np.average(f1010ij * f1010ij) - (np.average(f1010ij))**2.0 +
                2.2e-16)

            q1001i = phase.calc_phase_mean(np.array([q1d, q2d]), 1.0)
            q1010i = phase.calc_phase_mean(np.array([q1s, q2s]), 1.0)
            q1001istd = phase.calc_phase_std(np.append(q1jd, q2jd), 1.0)
            q1010istd = phase.calc_phase_std(np.append(q1js, q2js), 1.0)

            f1001i = f1001i * complex(np.cos(2.0 * np.pi * q1001i),
                                      np.sin(2.0 * np.pi * q1001i))
            f1010i = f1010i * complex(np.cos(2.0 * np.pi * q1010i),
                                      np.sin(2.0 * np.pi * q1010i))
            dbpmt.append([dbpms[i][0], dbpms[i][1]])

            if beam_direction == 1:
                fwqw[bn1] = [[f1001i, f1001istd, f1010i, f1010istd],
                             [q1001i, q1001istd, q1010i, q1010istd]]
            elif beam_direction == -1:
                fwqw[bn1] = [[f1010i, f1010istd, f1001i, f1001istd],
                             [q1010i, q1010istd, q1001i, q1001istd]]

    dbpms = dbpmt

    # compute global values
    CG = 0.0
    QG = 0.0
    CG_new = complex(0, 0)
    sumDiffDistance = 0
    count = 0
    for i in range(0, len(dbpms) - 2):
        bn1 = str.upper(dbpms[i][1])
        bn2 = str.upper(dbpms[i + 1][1])
        theInd_1 = MADTwiss.indx[bn1]
        theInd_2 = MADTwiss.indx[bn2]
        s1 = (MADTwiss.S[theInd_1])
        s2 = (MADTwiss.S[theInd_2])
        mux = MADTwiss.MUX[theInd_1]
        muy = MADTwiss.MUY[theInd_1]
        CG_new = CG_new + complex(fwqw[bn2][0][0].real,
                                  fwqw[bn2][0][0].imag) * np.exp(
                                      complex(0, 1) * 2 * np.pi * (mux - muy))
        #sumDiffDistance = sumDiffDistance + abs((s1-s2))
    CG_new_abs = 4 * abs(tune_x - tune_y) * abs(CG_new) / (len(dbpms))
    CG_new_phase = np.angle(CG_new)
    print 'NewCMINUS', CG_new_abs
    for i in range(0, len(dbpms) - 1):
        tw_x = list_zero_dpp_x[0]
        tw_y = list_zero_dpp_y[0]
        bn1 = str.upper(dbpms[i][1])
        CG += abs(fwqw[bn1][0][0])
        QG += fwqw[bn1][1][0] - (tw_x.MUX[tw_x.indx[bn1]] -
                                 tw_y.MUY[tw_y.indx[bn1]])

    # find operation point
    sign_QxmQy = _find_sign_QxmQy(outputpath, tune_x, tune_y)

    if len(dbpms) == 0:
        print >> sys.stderr, 'Warning: There is no BPM to output linear coupling properly... leaving Getcoupling.'
        fwqw['Global'] = [CG, QG]  #Quick fix Evian 2012
        return [fwqw, dbpms]
    else:
        CG_old = abs(4.0 * (tune_x - tune_y) * CG / len(dbpms))
        print 'OldCMINIS', CG_old
    fwqw['Global'] = [CG_new_abs, CG_new_phase]

    return [fwqw, dbpms]