def DCM_cal(filename=None,fseqfile='gainseq.fsq',dcmattn=None,missing='ant15',update=False): if filename is None: return 'Must specify ADC packet capture filename, e.g. "/dppdata1/PRT/PRT<yyyymmddhhmmss>adc.dat"' userpass = '******' fseq_handle = urllib2.urlopen('ftp://'+userpass+'acc.solar.pvt/parm/'+fseqfile,timeout=0.5) lines = fseq_handle.readlines() fseq_handle.close() for line in lines: if line.find('LIST:SEQUENCE') != -1: line = line[14:] bandlist = np.array(map(int,line.split(','))) if len(np.unique(bandlist)) != 34: print 'Frequency sequence must contain all bands [1-34]' return None # Read packet capture file adc = p.rd_jspec(filename) pwr = np.rollaxis(adc['phdr'],2)[:,:,:2] # Put measured power into uniform array arranged by band new_pwr = np.zeros((34,16,2)) for i in range(34): idx, = np.where(bandlist-1 == i) if len(idx) > 0: new_pwr[i] = np.median(pwr[idx],0) new_pwr.shape = (34,32) # Read table from the database. import cal_header import stateframe xml, buf = cal_header.read_cal(2) cur_table = stateframe.extract(buf,xml['Attenuation']) if dcmattn: # A DCM attenuation value was given, which presumes a constant value # so use it as the "original table." orig_table = np.zeros((34,30)) + dcmattn # orig_table[:,26:28] = 24 orig_table[:,28:] = 0 else: # No DCM attenuation value was given, so use current DCM master # table from the database. orig_table = cur_table attn = np.log10(new_pwr[:,:-2]/1600.)*10. # Zero any changes for missing antennas, and override orig_table with cur_table for those antennas if missing: idx = p.ant_str2list(missing) bad = np.sort(np.concatenate((idx*2,idx*2+1))) attn[:,bad] = 0 orig_table[:,bad] = cur_table[:,bad] new_table = (np.clip(orig_table + attn,0,30)/2).astype(int)*2 DCMlines = [] DCMlines.append('# Ant1 Ant2 Ant3 Ant4 Ant5 Ant6 Ant7 Ant8 Ant9 Ant10 Ant11 Ant12 Ant13 Ant14 Ant15') DCMlines.append('# X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y') DCMlines.append('# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----') for band in range(1,35): DCMlines.append('{:2} : {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2} {:2}'.format(band,*new_table[band-1])) return DCMlines
def xydla(filename, ant_str='ant1-14', apply=False): ''' Determine X vs. Y delay based on packet capture with Noise Diode on filename Name and path of a PRT (packet capture) file taken with ND-ON, using a fixed band, e.g. band15.fsq. Returns xy 14-element list of delays to apply, for use in second argument of cal_header.dla_update2sql() Optional argument: ant_str If supplied, is the standard specification of antennas to include. Antennas not included are updated with 0 (i.e. no change) apply If True, calls cal_header.dla_update2sql() and cal_header.dla_censql2table() to update X vs. Y delays ''' import matplotlib.pylab as plt from util import lobe f, ax = plt.subplots(4, 4) ants = p.ant_str2list(ant_str) ax.shape = (16) if type(filename) is dict: # Interpret input as an already read dictionary, rather than a filename, and skip # the slow process of reading it again. out = filename else: out = p.rd_jspec(filename) xy = [] chrange = np.arange( 2100, 3900) # Portion of 4096 sub-channel range to use for the fit npts = len(chrange) x = np.linspace( 0, np.pi * npts / 4096., 1800) # This makes phase slope come out in units of delay steps for i in range(14): if i in ants: ax[i].plot(np.angle(out['a'][i, 2, :, 30]), 'y.', label='Ant ' + str(i + 1)) res = np.polyfit(x, np.unwrap(np.angle(out['a'][i, 2, chrange, 30])), 1) ax[i].plot(chrange, lobe(np.polyval(res, x)), 'r.') ax[i].set_ylim(-4, 4) ax[i].legend(fontsize=9, loc='best', fancybox=True, framealpha=0.5) else: res = [0., 0.] xy.append(res[0]) if apply: import cal_header as ch ch.dla_update2sql(np.zeros(14, np.float), np.array(xy)) ch.dla_censql2table() return np.array(xy)
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
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