def get_free_phase_total_eq(MADTwiss,Files,Qd,Q,psid_ac2bpmac,plane,bd,op): #-- 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 BPM closest to the AC dipole and its position 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: 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]
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(cos(2.0*np.pi*q1001i),sin(2.0*np.pi*q1001i)) f1010i=f1010i*complex(cos(2.0*np.pi*q1010i),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 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=CG+math.sqrt(fwqw[bn1][0][0].real**2+fwqw[bn1][0][0].imag**2) QG=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=abs(4.0*(tune_x-tune_y)*CG/len(dbpms)) QG=(QG/len(dbpms)+0.5*(1.0-sign_QxmQy*0.5))%1.0 fwqw['Global']=[CG,QG] return [fwqw,dbpms]
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]
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 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]
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]
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]
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]
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]