def delay_centers(filename, satname, ants='ant1-13', band=23, doplot=False): ''' Reads specified 1-s capture file (specified as a filename string) and analyzes data in either the 3.5-4 GHz band (band 6) or the 12-12.5 GHz band (band 23). First finds the peak amplitude of the vector-summed measurements for delays, from -15 to 15 ns, on each baseline, and then applies the optimum delay needed to correct for the phase slope, optionally plotting the results. The keyword nants can be used to limit the solution to a smaller number of baselines. If doplot is True, plots an overview plot of the corrected phases, including the standard deviation of the fit as text in each box. TODO: It then optionally reads the delay_centers.txt file from the ACC and updates it. ''' # First see if we can read delay_centers.txt from the ACC (return if failure) userpass = '******' try: # Read delay center file from ACC dlafile = urllib2.urlopen('ftp://' + userpass + 'acc.solar.pvt/parm/delay_centers.txt', timeout=1) lines = dlafile.readlines() dcenx = [] dceny = [] for line in lines: if line[0] != '#': # Skip comment lines and takes next 2 numbers as delay # centers [ns] in X & Y dcenx.append(float(line.strip().split()[1])) dceny.append(float(line.strip().split()[2])) except: print Time().iso, 'ACC connection for delay centers timed out.' return [None] * 3 print 'Successfully read delay_centers.txt from ACC.' # Get satellite frequencies and polarizations (this is to use channel centers for fitting, # but is not yet completed) sat, = gs.get_sat_info(names=[satname]) if band == 23: freq = np.linspace(0, 4095, 4096) * 0.4 / 4096 + 12.15 elif band == 6: freq = np.linspace(0, 4095, 4096) * 0.4 / 4096 + 3.65 else: print 'Band MUST be either 23 (12-12.5 GHz) or 6 (3.5-4 GHz)' return None, None, None freqmhz = (freq * 10000. + 0.5).astype('int') / 10. pol = sat['pollist'] if band == 23: ridx, = np.where(pol == 'R') else: ridx, = np.where(pol == 'H') rfrq = sat['freqlist'][ridx] ridx = [] for f in rfrq: try: ridx.append(np.where(f == freqmhz)[0][0]) except: pass idxmin = ridx[0] if band == 23: lidx, = np.where(pol == 'L') else: lidx, = np.where(pol == 'V') lfrq = sat['freqlist'][lidx] lidx = [] for f in lfrq: try: lidx.append(np.where(f == freqmhz)[0][0]) except: pass idxmin = min(idxmin, lidx[0]) freq = freq[idxmin:] ant_list = ant_str2list(ants) nants = len(ant_list) nbl = nants * (nants - 1) / 2 # Create M arrays for nants antennas, and c arrays for nbl baselines Mx = np.zeros((nbl, nants)) My = np.zeros((nbl, nants)) cx = np.zeros(nbl, dtype='float') cy = np.zeros(nbl, dtype='float') # Read 1-s capture file of raw packets out = p.rd_jspec(filename) # Eliminate data on channels less than minimum, and perform sum over times out['x'] = out['x'][:, :, idxmin:, :].sum(3) out['a'] = out['a'][:, :, idxmin:, :].sum(3) print 'Successfully read file', filename # Get conversion from antenna pair (bl) to "data source" index bl2ord = p.bl_list() # Declare storage for delays in ns tau_xx = np.zeros((nants, nants), dtype='float') tau_yy = np.zeros((nants, nants), dtype='float') tau_xy = np.zeros((nants, nants), dtype='float') tau_yx = np.zeros((nants, nants), dtype='float') tau_ns = np.zeros((nants, nants), dtype='float') sigma = np.zeros((nants, nants), dtype='float') iblx = 0 ibly = 0 if doplot: f, ax = plt.subplots(nants, nants) f.subplots_adjust(hspace=0, wspace=0) for axrow in ax: for a in axrow: a.xaxis.set_visible(False) a.yaxis.set_visible(False) # Declare storage for auto-correlation (X vs. Y) delays in ns tau_a = np.zeros(nants, dtype='float') for i in range(nants): ai = ant_list[i] dat = out['a'][ai, 2] tau_a[i] = auto_delay_search(dat, freq) #plt.figure() for i in range(0, nants - 1): ai = ant_list[i] for j in range(i + 1, nants): aj = ant_list[j] dat = out['x'][bl2ord[ai, aj], 0] tau_0 = auto_delay_search(dat, freq) tau_xx[i] = delay_search(dat, freq, tau_0) dat = out['x'][bl2ord[ai, aj], 1] tau_0 = auto_delay_search(dat, freq) tau_yy[i] = delay_search(dat, freq, tau_0) if doplot: phi0 = tau_xx[i, j] * 2 * np.pi * freq phix = np.angle(out['x'][bl2ord[ai, aj], 0]) - phi0 phix -= phix[2048] ax[i, j].plot(freq, (phix + np.pi) % (2 * np.pi) - np.pi, '.') phi0 = tau_yy[i, j] * 2 * np.pi * freq phiy = np.angle(out['x'][bl2ord[ai, aj], 1]) - phi0 phiy -= phiy[2048] ax[j, i].plot(freq, (phiy + np.pi) % (2 * np.pi) - np.pi, '.') tau_ns[i, j] = tau_xx[i, j] # delay in nsec tau_ns[j, i] = tau_yy[i, j] # delay in nsec Mx[iblx, np.array((i, j))] = -1, 1 cx[iblx] = dcenx[aj] - dcenx[ai] - tau_ns[i, j] iblx += 1 My[ibly, np.array((i, j))] = -1, 1 cy[ibly] = dceny[aj] - dceny[ai] - tau_ns[j, i] ibly += 1 if doplot: # Set axis scales and label the plots for i in range(nants): ai = ant_list[i] ax[i, i].text(0.5, 0.5, str(ai + 1), ha='center', va='center', transform=ax[i, i].transAxes, fontsize=14) for j in range(nants): ax[i, j].set_xlim(freq[0], freq[-1]) ax[i, j].set_ylim(-np.pi, np.pi) print 'Successfully calculated delays from data.' # Obtain solution, only for those baselines with sigma < 1.0 xdla, xr, _, _ = np.linalg.lstsq(Mx[:iblx], cx[:iblx]) # For X channel ydla, yr, _, _ = np.linalg.lstsq(My[:ibly], cy[:ibly]) # For Y channel print 'Successfully analyzed delays for mutual consistency.' # Calculate new delays for ants based on Ant 1 as reference newdlax = xdla - xdla[0] + dcenx[0] newdlay = ydla - ydla[0] + dceny[0] - tau_a f = open('/tmp/delay_centers_tmp.txt', 'w') for line in lines: if line[0] == '#': print line, f.write(line) else: ant = int(line[:6]) idx, = np.where((ant - 1) == ant_list) if len(idx) == 0: # No update for this antenna fmt = '{:4d}*{:12.3f} {:12.3f} {:12.3f} {:12.3f}' print fmt.format(ant, dcenx[ant - 1], dceny[ant - 1], dcenx[ant - 1], dceny[ant - 1]) fmt = '{:4d} {:12.3f} {:12.3f}\n' f.write(fmt.format(ant, dcenx[ant - 1], dceny[ant - 1])) else: idx = idx[0] fmt = '{:4d} {:12.3f} {:12.3f} {:12.3f} {:12.3f}' print fmt.format(ant, dcenx[ant - 1], dceny[ant - 1], newdlax[idx], newdlay[idx]) fmt = '{:4d} {:12.3f} {:12.3f}\n' f.write(fmt.format(ant, newdlax[idx], newdlay[idx])) f.close() fmt = '{:6.2f} ' * nants for i in range(nants): print fmt.format(*tau_ns[i]) return tau_ns, xr, yr
def xy2rl(filename, satname): out = p.rd_jspec(filename) sat = gs.get_sat_info([satname])[0] freq = np.linspace(0,4095,4096)*0.4/4096 + 12.15 frq = sat['freqlist'] pol = sat['pollist'] freqmhz = (freq*10000. + 0.5).astype('int')/10. ridx, = np.where(pol == 'R') lidx, = np.where(pol == 'L') rfrq = frq[ridx] ridx = [] for f in rfrq: try: ridx.append(np.where(f == freqmhz)[0][0]) except: pass ridx = np.array(ridx) nant = 13 ipol = np.zeros((nant,4096),dtype='float') vpol = np.zeros((nant,4096),dtype='float') rpol = np.zeros((nant,4096),dtype='float') lpol = np.zeros((nant,4096),dtype='float') for k in range(nant): xx,yy,xy,yx = out['a'][k,:,:,30] pfitr = np.polyfit(freq[ridx],unwrap(angle(xy[ridx])),1) phi = polyval(pfitr,freq) xyp = xy*(cos(phi+pi/2)-1j*sin(phi+pi/2)) yxp = yx*(cos(phi+pi/2)+1j*sin(phi+pi/2)) ipol[k] = abs(xx+yy) vpol[k] = imag(yxp - xyp) rpol[k] = real(xx+yy) + imag(yxp - xyp) lpol[k] = real(xx+yy) - imag(yxp - xyp) # Normalize to antenna 6 IPOL (kind of random) fac = ipol/ipol[5,:] f, ax = subplots(4,1) for k in range(nant): ax[0].plot(freq,ipol[k]/fac[k]) ax[1].plot(freq,vpol[k]/fac[k]) ax[2].plot(freq,rpol[k]/fac[k]) ax[3].plot(freq,lpol[k]/fac[k]) ax[0].text(0.05,0.8,'Stokes I',transform=ax[0].transAxes,fontsize=12) ax[1].text(0.05,0.8,'Stokes V',transform=ax[1].transAxes,fontsize=12) ax[2].text(0.05,0.8,'RCP',transform=ax[2].transAxes,fontsize=12) ax[3].text(0.05,0.8,'LCP',transform=ax[3].transAxes,fontsize=12) for i in range(4): yrng = ax[i].yaxis.get_data_interval() ax[i].set_xlim(ax[i].xaxis.get_data_interval()) for j in range(len(frq)): if pol[j] == 'R': ax[i].plot(frq[j]*ones(2)/1000.,yrng,color='red',linewidth=2) else: ax[i].plot(frq[j]*ones(2)/1000.,yrng,color='green',linewidth=2) f.suptitle(sat['name']+' Communication Satellite',fontsize=18) ax[3].set_xlabel('Frequency [GHz]') if sat['name'] == 'Ciel-2': ax[3].annotate('Beacon',(12.209,14000),xytext=(12.17,30000),arrowprops=dict(width=2,headwidth=6,frac=0.2,facecolor='black', shrink=0.05)) show() return ipol,vpol,rpol,lpol
def delay_centers(filename,satname,ants='ant1-13',band=23,doplot=False): ''' Reads specified 1-s capture file (specified as a filename string) and analyzes data in either the 3.5-4 GHz band (band 6) or the 12-12.5 GHz band (band 23). First finds the peak amplitude of the vector-summed measurements for delays, from -15 to 15 ns, on each baseline, and then applies the optimum delay needed to correct for the phase slope, optionally plotting the results. The keyword nants can be used to limit the solution to a smaller number of baselines. If doplot is True, plots an overview plot of the corrected phases, including the standard deviation of the fit as text in each box. TODO: It then optionally reads the delay_centers.txt file from the ACC and updates it. ''' # First see if we can read delay_centers.txt from the ACC (return if failure) userpass = '******' try: # Read delay center file from ACC dlafile = urllib2.urlopen('ftp://'+userpass+'acc.solar.pvt/parm/delay_centers.txt',timeout=1) lines = dlafile.readlines() dcenx = [] dceny = [] for line in lines: if line[0] != '#': # Skip comment lines and takes next 2 numbers as delay # centers [ns] in X & Y dcenx.append(float(line.strip().split()[1])) dceny.append(float(line.strip().split()[2])) except: print Time().iso,'ACC connection for delay centers timed out.' return [None]*3 print 'Successfully read delay_centers.txt from ACC.' # Get satellite frequencies and polarizations (this is to use channel centers for fitting, # but is not yet completed) sat, = gs.get_sat_info(names=[satname]) if band == 23: freq = np.linspace(0,4095,4096)*0.4/4096 + 12.15 elif band ==6: freq = np.linspace(0,4095,4096)*0.4/4096 + 3.65 else: print 'Band MUST be either 23 (12-12.5 GHz) or 6 (3.5-4 GHz)' return None, None, None freqmhz = (freq*10000. + 0.5).astype('int')/10. pol = sat['pollist'] if band == 23: ridx, = np.where(pol == 'R') else: ridx, = np.where(pol == 'H') rfrq = sat['freqlist'][ridx] ridx = [] for f in rfrq: try: ridx.append(np.where(f == freqmhz)[0][0]) except: pass idxmin = ridx[0] if band == 23: lidx, = np.where(pol == 'L') else: lidx, = np.where(pol == 'V') lfrq = sat['freqlist'][lidx] lidx = [] for f in lfrq: try: lidx.append(np.where(f == freqmhz)[0][0]) except: pass idxmin = min(idxmin,lidx[0]) freq = freq[idxmin:] ant_list = ant_str2list(ants) nants = len(ant_list) nbl = nants*(nants-1)/2 # Create M arrays for nants antennas, and c arrays for nbl baselines Mx = np.zeros((nbl,nants)) My = np.zeros((nbl,nants)) cx = np.zeros(nbl,dtype='float') cy = np.zeros(nbl,dtype='float') # Read 1-s capture file of raw packets out = p.rd_jspec(filename) # Eliminate data on channels less than minimum, and perform sum over times out['x'] = out['x'][:,:,idxmin:,:].sum(3) out['a'] = out['a'][:,:,idxmin:,:].sum(3) print 'Successfully read file',filename # Get conversion from antenna pair (bl) to "data source" index bl2ord = p.bl_list() # Declare storage for delays in ns tau_xx = np.zeros((nants,nants),dtype='float') tau_yy = np.zeros((nants,nants),dtype='float') tau_xy = np.zeros((nants,nants),dtype='float') tau_yx = np.zeros((nants,nants),dtype='float') tau_ns = np.zeros((nants,nants),dtype='float') sigma = np.zeros((nants,nants),dtype='float') iblx = 0 ibly = 0 if doplot: f, ax = plt.subplots(nants,nants) f.subplots_adjust(hspace=0,wspace=0) for axrow in ax: for a in axrow: a.xaxis.set_visible(False) a.yaxis.set_visible(False) # Declare storage for auto-correlation (X vs. Y) delays in ns tau_a = np.zeros(nants,dtype='float') for i in range(nants): ai = ant_list[i] dat = out['a'][ai,2] tau_a[i] = auto_delay_search(dat,freq) #plt.figure() for i in range(0,nants-1): ai = ant_list[i] for j in range(i+1,nants): aj = ant_list[j] dat = out['x'][bl2ord[ai,aj],0] tau_0 = auto_delay_search(dat,freq) tau_xx[i] = delay_search(dat,freq,tau_0) dat = out['x'][bl2ord[ai,aj],1] tau_0 = auto_delay_search(dat,freq) tau_yy[i] = delay_search(dat,freq,tau_0) if doplot: phi0 = tau_xx[i,j]*2*np.pi*freq phix = np.angle(out['x'][bl2ord[ai,aj],0]) - phi0 phix -= phix[2048] ax[i,j].plot(freq, (phix + np.pi) % (2*np.pi) - np.pi , '.') phi0 = tau_yy[i,j]*2*np.pi*freq phiy = np.angle(out['x'][bl2ord[ai,aj],1]) - phi0 phiy -= phiy[2048] ax[j,i].plot(freq, (phiy + np.pi) % (2*np.pi) - np.pi, '.') tau_ns[i,j] = tau_xx[i,j] # delay in nsec tau_ns[j,i] = tau_yy[i,j] # delay in nsec Mx[iblx,np.array((i,j))] = -1,1 cx[iblx] = dcenx[aj] - dcenx[ai] - tau_ns[i,j] iblx += 1 My[ibly,np.array((i,j))] = -1,1 cy[ibly] = dceny[aj] - dceny[ai] - tau_ns[j,i] ibly += 1 if doplot: # Set axis scales and label the plots for i in range(nants): ai = ant_list[i] ax[i,i].text(0.5,0.5,str(ai+1),ha='center',va='center',transform=ax[i,i].transAxes,fontsize=14) for j in range(nants): ax[i,j].set_xlim(freq[0],freq[-1]) ax[i,j].set_ylim(-np.pi,np.pi) print 'Successfully calculated delays from data.' # Obtain solution, only for those baselines with sigma < 1.0 xdla,xr,_,_ = np.linalg.lstsq(Mx[:iblx],cx[:iblx]) # For X channel ydla,yr,_,_ = np.linalg.lstsq(My[:ibly],cy[:ibly]) # For Y channel print 'Successfully analyzed delays for mutual consistency.' # Calculate new delays for ants based on Ant 1 as reference newdlax = xdla - xdla[0] + dcenx[0] newdlay = ydla - ydla[0] + dceny[0] - tau_a f = open('/tmp/delay_centers_tmp.txt','w') for line in lines: if line[0] == '#': print line, f.write(line) else: ant = int(line[:6]) idx, = np.where((ant-1) == ant_list) if len(idx) == 0: # No update for this antenna fmt = '{:4d}*{:12.3f} {:12.3f} {:12.3f} {:12.3f}' print fmt.format(ant,dcenx[ant-1],dceny[ant-1],dcenx[ant-1],dceny[ant-1]) fmt = '{:4d} {:12.3f} {:12.3f}\n' f.write(fmt.format(ant,dcenx[ant-1],dceny[ant-1])) else: idx = idx[0] fmt = '{:4d} {:12.3f} {:12.3f} {:12.3f} {:12.3f}' print fmt.format(ant,dcenx[ant-1],dceny[ant-1],newdlax[idx],newdlay[idx]) fmt = '{:4d} {:12.3f} {:12.3f}\n' f.write(fmt.format(ant,newdlax[idx],newdlay[idx])) f.close() fmt = '{:6.2f} '*nants for i in range(nants): print fmt.format(*tau_ns[i]) return tau_ns, xr, yr