def summary_plot(out,ant_str='ant1-13',ptype='phase',pol='XX-YY'): ''' Makes a summary amplitude or phase plot for all baselines from ants in ant_str in out dictionary. ''' import matplotlib.pyplot as plt ant_list = p.ant_str2list(ant_str) nant = len(ant_list) if ptype != 'amp' and ptype != 'phase': print "Invalid plot type. Must be 'amp' or 'phase'." return poloff = 0 if pol != 'XX-YY': poloff = 2 f, ax = plt.subplots(nant,nant) f.subplots_adjust(hspace=0,wspace=0) bl2ord = p.bl_list() for axrow in ax: for a in axrow: a.xaxis.set_visible(False) a.yaxis.set_visible(False) for i in range(nant-1): ai = ant_list[i] for j in range(i+1,nant): aj = ant_list[j] if ptype == 'phase': ax[i,j].imshow(np.angle(out['x'][bl2ord[ai,aj],0+poloff])) ax[j,i].imshow(np.angle(out['x'][bl2ord[ai,aj],1+poloff])) elif ptype == 'amp': ax[i,j].imshow(np.abs(out['x'][bl2ord[ai,aj],0+poloff])) ax[j,i].imshow(np.abs(out['x'][bl2ord[ai,aj],1+poloff])) for i in range(nant): 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)
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 summary_plot(out, ant_str='ant1-13', ptype='phase', pol='XX-YY'): ''' Makes a summary amplitude or phase plot for all baselines from ants in ant_str in out dictionary. ''' import matplotlib.pyplot as plt ant_list = p.ant_str2list(ant_str) nant = len(ant_list) if ptype != 'amp' and ptype != 'phase': print "Invalid plot type. Must be 'amp' or 'phase'." return poloff = 0 if pol != 'XX-YY': poloff = 2 f, ax = plt.subplots(nant, nant) f.subplots_adjust(hspace=0, wspace=0) bl2ord = p.bl_list() for axrow in ax: for a in axrow: a.xaxis.set_visible(False) a.yaxis.set_visible(False) for i in range(nant - 1): ai = ant_list[i] for j in range(i + 1, nant): aj = ant_list[j] if ptype == 'phase': ax[i, j].imshow(np.angle(out['x'][bl2ord[ai, aj], 0 + poloff])) ax[j, i].imshow(np.angle(out['x'][bl2ord[ai, aj], 1 + poloff])) elif ptype == 'amp': ax[i, j].imshow(np.abs(out['x'][bl2ord[ai, aj], 0 + poloff])) ax[j, i].imshow(np.abs(out['x'][bl2ord[ai, aj], 1 + poloff])) for i in range(nant): 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)
def getphasecor(data, ant_str='ant1-14', polist=[0, 1], crange=[0, 4095], pplot=False): ''' Routine adapted from Maria Loukitcheva's code, to find phase slopes in correlated data on a geosynchronous satellite. ''' def movingaverage(interval, window_size): # Range of ones, scaled for unit area window = np.ones(int(window_size)) / np.float(window_size) return np.convolve(interval, window, 'same') antlist = p.ant_str2list(ant_str) print antlist + 1 ndon = False if len(data[:, 0, 0, 0]) == 16: ndon = True if ndon: chlist = antlist else: chlist = antlist[1:] - 1 bl2ord = p.bl_list() if not ndon: data = data[bl2ord[0, 1:]] # Consider only baselines with antenna 1 print data.shape pcor = np.linspace(0, np.pi, 4096) istep = np.arange(-50, 50) # Range of steps to search chan = np.arange(4096) phasecor = np.zeros((14, len(polist))) start = crange[0] end = crange[1] #antennalist=[2] if pplot: import matplotlib.pylab as plt f, ax = plt.subplots(len(antlist), len(polist)) for i, iant in enumerate(chlist): for j, jpol in enumerate(polist): phaseall = np.zeros(len(istep)) for k in range(len(istep)): #if movaver: # aver = movingaverage(data[bl2ord[0, antennalist[i]], j, :, 0],201) # aver = cos(angle(aver) + istep[k] * pcor) #else: aver = np.cos( 2 * (np.angle(data[iant, jpol, :, 0]) + istep[k] * pcor)) phaseall[k] = np.polyfit(chan[start:end], aver[start:end], 0, full=True)[1] #print phaseall #print argmin(drange) #print corind[argmin(drange)] ioff = iant + 1 if ndon: ioff = iant phasecor[ioff, j] = -istep[np.argmin( phaseall)] # Correct delay is negative of the phase correction phas0 = np.angle(data[iant, jpol, :, 0]) phas = phas0 + istep[np.argmin(phaseall)] * pcor if pplot: if ndon: iax = i else: iax = i + 1 if len(polist) > 1: ax[iax, j].plot(phas0 % (2 * np.pi), '.') ax[iax, j].plot(phas % (2 * np.pi), '.') ax[iax, j].plot(chan[start:end], phas[start:end] % (2 * np.pi), color='white') ax[iax, j].set_ylim(-1, 7) else: ax[iax].plot(phas0 % (2 * np.pi), '.') ax[iax].plot(phas % (2 * np.pi), '.') ax[iax].plot(chan[start:end], phas[start:end] % (2 * np.pi), color='white') ax[iax].set_ylim(-1, 7) if len(polist) == 1: # Reduce two-dimensional array with second dimension = 1 to a single dimension return phasecor[:, 0] return phasecor