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 flag_sk(out): bl2ord = p.bl_list() m = out['m'] sk = (m + 1.) / (m - 1.) * (m * out['p2'] / (out['p']**2) - 1) u_lim = 1.25 l_lim = 0.75 sk_flag = np.logical_or(sk > u_lim, sk < l_lim) nant, npol, nf, nt = m.shape for i in range(nant - 1): for j in range(i + 1, nant): flags = np.logical_or(sk_flag[i], sk_flag[j]) out['x'][bl2ord[i, j], flags] = np.nan for i in range(nant): if 'meanp' in out: out['meanp'][i, sk_flag[i]] = np.nan out['a'][i, sk_flag[i]] = np.nan return out
def flag_sk(out): bl2ord = p.bl_list() m = out['m'] sk = (m+1.)/(m-1.)*(m*out['p2']/(out['p']**2) - 1) u_lim = 1.25 l_lim = 0.75 sk_flag = np.logical_or(sk > u_lim,sk < l_lim) nant,npol,nf,nt = m.shape for i in range(nant-1): for j in range(i+1,nant): flags = np.logical_or(sk_flag[i],sk_flag[j]) out['x'][bl2ord[i,j],flags] = np.nan for i in range(nant): if 'meanp' in out: out['meanp'][i,sk_flag[i]] = np.nan out['a'][i,sk_flag[i]] = np.nan return out
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
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 readXdata(filename, filter=False, tp_only=False): ''' This routine reads the data from a single IDBfile. Optiona Keywords: filter boolean--if True, returns only non-zero frequencies if False (default), returns uniform set of 500 frequencies tp_only boolean--if True, returns only TP information if False (default), returns everything (including auto & cross correlations) ''' # Open uv file for reading uv = aipy.miriad.UV(filename) good_idx = np.arange(len(uv['sfreq'])) if filter: good_idx = [] # Read a bunch of records to get number of good frequencies, i.e. those with at least # some non-zero data. Read 20 records for baseline 1-2, XX pol uv.select('antennae', 0, 2, include=True) uv.select('polarization', -5, -5, include=True) for i in range(20): preamble, data = uv.read() idx, = data.nonzero() if len(idx) > len(good_idx): good_idx = copy.copy(idx) uv.select('clear', 0, 0) uv.rewind() if 'source' in uv.vartable: src = uv['source'] nf = len(good_idx) freq = uv['sfreq'][good_idx] npol = uv['npol'] nants = uv['nants'] nbl = nants * (nants - 1) / 2 bl2ord = p.bl_list(nants) if not tp_only: outa = np.zeros((nants, npol, nf, 600), dtype=np.complex64) # Auto-correlations outx = np.zeros((nbl, npol, nf, 600), dtype=np.complex64) # Cross-correlations outp = np.zeros((nants, 2, nf, 600), dtype=np.float) outp2 = np.zeros((nants, 2, nf, 600), dtype=np.float) outm = np.zeros((nants, 2, nf, 600), dtype=np.int) uvwarray = np.zeros((nbl, 600, 3), dtype=np.float) timearray = [] l = -1 tprev = 0 tsav = 0 # Use antennalist if available if 'antlist' in uv.vartable: ants = uv['antlist'] antlist = map(int, ants.split()) else: antlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] for preamble, data in uv.all(): uvw, t, (i0, j0) = preamble i = antlist.index(i0 + 1) j = antlist.index(j0 + 1) if i > j: # Reverse order of indices j = antlist.index(i0 + 1) i = antlist.index(j0 + 1) # Assumes uv['pol'] is one of -5, -6, -7, -8 k = -5 - uv['pol'] if filter: if len(data.nonzero()[0]) == nf: if t != tprev: # print preamble # New time l += 1 if l == 600: break tprev = t timearray.append(t) xdata = uv['xsampler'].reshape(500, nants, 3) ydata = uv['ysampler'].reshape(500, nants, 3) outp[:, 0, :, l] = np.swapaxes(xdata[good_idx, :, 0], 0, 1) outp[:, 1, :, l] = np.swapaxes(ydata[good_idx, :, 0], 0, 1) outp2[:, 0, :, l] = np.swapaxes(xdata[good_idx, :, 1], 0, 1) outp2[:, 1, :, l] = np.swapaxes(ydata[good_idx, :, 1], 0, 1) outm[:, 0, :, l] = np.swapaxes(xdata[good_idx, :, 2], 0, 1) outm[:, 1, :, l] = np.swapaxes(ydata[good_idx, :, 2], 0, 1) if tp_only: outa = None outx = None else: if i0 == j0: # This is an auto-correlation outa[i0, k, :, l] = data[data.nonzero()] else: outx[bl2ord[i, j], k, :, l] = data[data.nonzero()] if k == 3: uvwarray[bl2ord[i, j], l] = uvw[data.nonzero()] else: if t != tprev: # New time l += 1 if l == 600: break tprev = t timearray.append(t) xdata = uv['xsampler'].reshape(500, nants, 3) ydata = uv['ysampler'].reshape(500, nants, 3) outp[:, 0, :, l] = np.swapaxes(xdata[:, :, 0], 0, 1) outp[:, 1, :, l] = np.swapaxes(ydata[:, :, 0], 0, 1) outp2[:, 0, :, l] = np.swapaxes(xdata[:, :, 1], 0, 1) outp2[:, 1, :, l] = np.swapaxes(ydata[:, :, 1], 0, 1) outm[:, 0, :, l] = np.swapaxes(xdata[:, :, 2], 0, 1) outm[:, 1, :, l] = np.swapaxes(ydata[:, :, 2], 0, 1) if tp_only: outa = None outx = None else: if i0 == j0: # This is an auto-correlation outa[i0, k, :, l] = data if k < 2 and np.sum(data != np.real(data)) > 0: print preamble, uv['pol'], 'has imaginary data!' else: outx[bl2ord[i, j], k, :, l] = data if k == 3: uvwarray[bl2ord[i, j], l] = uvw # Truncate in case of early end of data nt = len(timearray) outp = outp[:, :, :, :nt] outp2 = outp2[:, :, :, :nt] outm = outm[:, :, :, :nt] outa = outa[:, :, :, :nt] outx = outx[:, :, :, :nt] out = { 'a': outa, 'x': outx, 'uvw': uvwarray, 'fghz': freq, 'time': np.array(timearray), 'source': src, 'p': outp, 'p2': outp2, 'm': outm } return out
def readXdatmp(filename): # This temporary routine reads the data from a single IDBfile where the # polarization was written incorrectly. (-1,-2,0,0) instead of (-5,-6,-7,-8) # the IDB array sorts basline pairs into correct order for an output # array that just has 18 baselines (2 sets of 4 antennas correlated separately # now just need to convert i,j into slot in 136-slot array: 15*16/2 corrs +16 auto # this array corresponds to the first index (auto corr) for each antenna # 16*(iant-1)-(iant-1)(iant-2)/2 ibl = np.array([ 0, 16, 31, 45, 58, 70, 81, 91, 100, 108, 115, 121, 126, 130, 133, 135 ]) # Open uv file for reading uv = aipy.miriad.UV(filename) good_idx = [] # Read a bunch of records to get number of good frequencies, i.e. those with at least # some non-zero data. Read 20 records for baseline 1-2, XX pol uv.select('antennae', 0, 2, include=True) uv.select('polarization', -1, -1, include=True) for i in range(20): preamble, data = uv.read() idx, = data.nonzero() if len(idx) > len(good_idx): good_idx = copy.copy(idx) if 'source' in uv.vartable: src = uv['source'] uv.select('clear', 0, 0) uv.rewind() nf = len(good_idx) freq = uv['sfreq'][good_idx] npol = uv['npol'] nants = uv['nants'] nbl = nants * (nants - 1) / 2 bl2ord = p.bl_list(nants) outa = np.zeros((nants, npol, nf, 600), dtype=np.complex64) # Auto-correlations outx = np.zeros((nbl, npol, nf, 600), dtype=np.complex64) # Cross-correlations outp = np.zeros((nants, 2, nf, 600), dtype=np.float) outp2 = np.zeros((nants, 2, nf, 600), dtype=np.float) outm = np.zeros((nants, 2, nf, 600), dtype=np.int) uvwarray = [] timearray = [] l = -1 tprev = 0 # Use antennalist if available if 'antlist' in uv.vartable: ants = uv['antlist'] antlist = map(int, ants.split()) else: antlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] kp = 0 for preamble, data in uv.all(): uvw, t, (i0, j0) = preamble i = antlist.index(i0 + 1) j = antlist.index(j0 + 1) if i > j: # Reverse order of indices j = antlist.index(i0 + 1) i = antlist.index(j0 + 1) # Assumes uv['pol'] is -1, -2, 0, 0 if i == 0 and j == 0: if uv['pol'] == -1: k = 0 elif uv['pol'] == -2: k = 1 elif uv['pol'] == 0: if kp == 1: k = 2 kp = 0 else: k = 3 kp = 1 if k == 3: uvwarray.append(uvw) if len(data.nonzero()[0]) == nf: if t != tprev: # New time l += 1 if l == 600: break tprev = t timearray.append(t) xdata = uv['xsampler'].reshape(500, nants, 3) ydata = uv['ysampler'].reshape(500, nants, 3) outp[:, 0, :, l] = np.swapaxes(xdata[good_idx, :, 0], 0, 1) outp[:, 1, :, l] = np.swapaxes(ydata[good_idx, :, 0], 0, 1) outp2[:, 0, :, l] = np.swapaxes(xdata[good_idx, :, 1], 0, 1) outp2[:, 1, :, l] = np.swapaxes(ydata[good_idx, :, 1], 0, 1) outm[:, 0, :, l] = np.swapaxes(xdata[good_idx, :, 2], 0, 1) outm[:, 1, :, l] = np.swapaxes(ydata[good_idx, :, 2], 0, 1) if i0 == j0: # This is an auto-correlation outa[i0, k, :, l] = data[data.nonzero()] else: outx[bl2ord[i, j], k, :, l] = data[data.nonzero()] out = { 'a': outa, 'x': outx, 'uvw': np.array(uvwarray), 'fghz': freq, 'time': np.array(timearray), 'source': src, 'p': outp, 'p2': outp2, 'm': outm } return out
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
import numpy as np import matplotlib.pylab as plt from pcapture2 import bl_list bl2ord = bl_list() def rot_sim(indict): ''' Simulates effect of non-ideal feed behavior on input data for a single baseline. If 'unrot' is true, it takes the data as output data and applies the inverse of the corresponding Mueller matrix to it. Input is a dictionary (indict) with the following keys (and their defaults if omitted) 'data' : 4 x ntimes array of data, corresponding to a set of XX, XY, YX, YY, in that order, for each time. No default (error return if omitted) 'chi1' : Parallactic (or rotation) angle of first antenna (default 0) (scalar or ntimes array) 'chi2' : Parallactic (or rotation) angle of second antenna (default 0) (scalar or ntimes array) 'a1' : Relative amplitude of Y wrt X for first antenna (default 1) 'a2' : Relative amplitude of Y wrt X for second antenna (default 1) 'd1' : Relative cross-talk between X and Y for first antenna (default 0) 'd2' : Relative cross-talk between X and Y for second antenna (default 0) 'unrot': Whether to rotate or unrotate the input data (default False) 'verbose': Print some diagnostic messages 'doplot': Create some plots of the before and after amplitudes and phases Result is a plot of input and output. Returns the rotated or unrotated data in the same form as the input data. ''' # Input is a dictionary, contained needed keys. Any missing # keys are filled in with defaults: data = indict.get('data') # No default if data is None:
def idb_readXdata(filename, filter=False): '''This routine reads the data from a single IDBfile. Optional Keywords: filter boolean--if True, returns only non-zero frequencies if False (default), returns all frequencies. This differs from Dale's version in that it includes all correlations, drops the tp_only option, and the outputs that are not in the UDB files. ''' # Open uv file for reading uv = aipy.miriad.UV(filename) nf_orig = len(uv['sfreq']) good_idx = np.arange(nf_orig) if filter: good_idx = [] # Read a bunch of records to get number of good frequencies, # i.e. those with at least some non-zero data. Read 20 # records for baseline 1-2, XX pol uv.select('antennae',0,2,include=True) uv.select('polarization',-5,-5,include=True) for i in range(20): preamble, data = uv.read() idx, = data.nonzero() if len(idx) > len(good_idx): good_idx = copy.copy(idx) uv.select('clear',0,0) uv.rewind() #endif #set up outputs nf = len(good_idx) print 'NF: ', nf freq = uv['sfreq'][good_idx] npol = uv['npol'] polarr = np.array([-5, -6, -7, -8]) nants = uv['nants'] nbl = nants*(nants-1)/2 nblc = nbl+nants # all-correlations, add a mask for the output vis array outx0 = np.zeros((nf, nblc, npol, 600),dtype=np.complex64) omask = np.zeros((nf, nblc, npol, 600),dtype=np.int32) outx = ma.masked_array(outx0, mask = omask) i0array = np.zeros((nblc, 600), dtype = np.int32) j0array = np.zeros((nblc, 600), dtype = np.int32) outpx = np.zeros((nf*nants, 600), dtype=np.float) outpy = np.zeros((nf*nants, 600), dtype=np.float) uvwarray = np.zeros((3, nblc, 600), dtype=np.float) delayarray = np.zeros((nants, 600), dtype=np.float) #lists for time arrays utarray = [] timearray = [] lstarray = [] l = -1 tprev = 0 tsav = 0 # Use antennalist if available if 'antlist' in uv.vartable: ants = strip_non_printable(uv['antlist']) antlist = map(int, ants.split()) else: antlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] #endelse #keep autocorrelations in the array bl2ord = p.bl_list() for ij in range(len(antlist)): bl2ord[ij, ij] = nbl+ij #endfor for preamble, data in uv.all(): uvw, t, (i0,j0) = preamble i = antlist.index(i0+1) j = antlist.index(j0+1) if i > j: # Reverse order of indices j = antlist.index(i0+1) i = antlist.index(j0+1) #endif # Assumes uv['pol'] is one of -5, -6, -7, -8 k = -5 - uv['pol'] if filter: if len(data.nonzero()[0]) == nf: if t != tprev: # New time l += 1 if l == 600: break #endif tprev = t timearray.append(t) utarray.append(uv['ut']) try: lstarray.append(uv['lst']) except: pass #endexcept xdata0 = uv['xsampler'].reshape(nf_orig,nants,3) xdata = xdata0[good_idx, :, 0] outpx[:,l] = xdata.reshape(nf*nants) ydata0 = uv['ysampler'].reshape(nf_orig,nants,3) ydata = ydata0[good_idx, :, 0] outpy[:,l] = ydata.reshape(nf*nants) delayarray[:,l] = uv['delay'] #endif outx[:, bl2ord[i,j],k,l] = data[data.nonzero()] if k == 3: uvwarray[:, bl2ord[i,j],l] = uvw i0array[bl2ord[i,j],l] = i0 j0array[bl2ord[i,j],l] = j0 #endif #endif, for len(data.nonzero()) == nf else: if t != tprev: # New time l += 1 if l == 600: break tprev = t timearray.append(t) utarray.append(uv['ut']) try: lstarray.append(uv['lst']) except: pass #endexcept xdata = uv['xsampler'].reshape(nf,nants,3) outpx[:,l] = xdata[:, :, 0].reshape(nf*nants) ydata = uv['ysampler'].reshape(nf,nants,3) outpy[:,l] = ydata[:, :, 0].reshape(nf*nants) delayarray[:,l] = uv['delay'] #endif outx[:,bl2ord[i,j],k,l] = data if k == 3: uvwarray[:,bl2ord[i,j],l] = uvw i0array[bl2ord[i,j],l] = i0 j0array[bl2ord[i,j],l] = j0 #endif #endelse (not filter) #endfor # Truncate in case of early end of data nt = len(timearray) outpx = outpx[:,:nt] outpy = outpy[:,:nt] outx = outx[:,:,:,:nt] uvwarray = uvwarray[:, :, :nt] delayarray = delayarray[:, :nt] if len(lstarray) != 0: pass else: tarray = Time(timearray,format='jd') for t in tarray: lstarray.append(el.eovsa_lst(t)) #endfor #endelse #i0 and j0 should always be the same i0array = i0array[:,0] j0array = j0array[:,0] #timearray, lstarray and utarray are lists out = {'x':outx,'uvw':uvwarray,'time':np.array(timearray),'px':outpx,'py':outpy,'i0':i0array,'j0':j0array,'lst':np.array(lstarray),'pol':polarr,'delay':delayarray,'ut':np.array(utarray),'file0':filename} return out
def readXdata(filename): '''This routine reads the data from a single UDB file. ''' # Open uv file for reading uv = aipy.miriad.UV(filename) # Read all to get a time array utcount = 0 ut = 0.0 for preamble, data in uv.all(): # Look for time change if preamble[1] != ut: ut = preamble[1] utcount = utcount+1 #endif #endfor uv.rewind() #set up outputs src = uv['source'] sfreq = uv['sfreq'] nf = len(sfreq) sdf = uv['sdf'] npol = uv['npol'] polarr = np.array([-5, -6, -7, -8]) nants = uv['nants'] nbl = nants*(nants-1)/2 nblc = nants+nbl # all-correlations, add a mask for the output vis array outx0 = np.zeros((nf, nblc, npol, utcount),dtype=np.complex64) omask = np.zeros((nf, nblc, npol, utcount),dtype=np.int32) outx = ma.masked_array(outx0, mask = omask) i0array = np.zeros((nblc, utcount), dtype = np.int32) j0array = np.zeros((nblc, utcount), dtype = np.int32) outpx = np.zeros((nants*nf, utcount), dtype=np.float) outpy = np.zeros((nants*nf, utcount), dtype=np.float) uvwarray = np.zeros((3, nblc, utcount), dtype=np.float) delayarray = np.zeros((nants, utcount), dtype=np.float) utarray = [] timearray = [] lstarray = [] l = -1 tprev = 0 tsav = 0 # Use antennalist if available if 'antlist' in uv.vartable: ants = strip_non_printable(uv['antlist']) antlist = map(int, ants.split()) else: antlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] #endelse #keep autocorrelations in the array bl2ord = p.bl_list() for ij in range(len(antlist)): bl2ord[ij, ij] = nbl+ij #endfor xxx = 0 for preamble, data in uv.all(): uvw, t, (i0,j0) = preamble i = antlist.index(i0+1) j = antlist.index(j0+1) if i > j: #this should not happen post-2016 # Reverse order of indices j = antlist.index(i0+1) i = antlist.index(j0+1) # Assumes uv['pol'] is one of -5, -6, -7, -8 # Endif k = -5 - uv['pol'] if t != tprev: # New time l += 1 if l == utcount: break #endif tprev = t try: lstarray.append(uv['lst']) except: pass timearray.append(t) utarray.append(uv['ut']) xdata = uv['xtsys'] ydata = uv['ytsys'] outpx[:, l] = xdata outpy[:, l] = ydata delayarray[:, l] = uv['delay'] #endif outx[:,bl2ord[i,j],k,l] = data #apply mask outx[:,bl2ord[i,j],k,l].mask = data.mask if k == 3: uvwarray[:, bl2ord[i,j],l] = uvw i0array[bl2ord[i,j],l] = i0 j0array[bl2ord[i,j],l] = j0 #endif #endfor if len(lstarray) != 0: pass else: tarray = Time(timearray,format='jd') for t in tarray: lstarray.append(el.eovsa_lst(t)) #endfor #endelse #i0 and j0 should always be the same i0array = i0array[:,0] j0array = j0array[:,0] #timearray, lstarray and utarray are lists out = {'x':outx,'uvw':uvwarray,'time':np.array(timearray),'px':outpx,'py':outpy,'i0':i0array,'j0':j0array,'lst':np.array(lstarray),'pol':polarr,'delay':delayarray,'ut':np.array(utarray),'file0':filename} return out
def readXdata(filename, filter=False, tp_only=False): ''' This routine reads the data from a single IDBfile. Optiona Keywords: filter boolean--if True, returns only non-zero frequencies if False (default), returns uniform set of 500 frequencies tp_only boolean--if True, returns only TP information if False (default), returns everything (including auto & cross correlations) ''' # Open uv file for reading uv = aipy.miriad.UV(filename) good_idx = np.arange(len(uv['sfreq'])) if filter: good_idx = [] # Read a bunch of records to get number of good frequencies, i.e. those with at least # some non-zero data. Read 20 records for baseline 1-2, XX pol uv.select('antennae',0,2,include=True) uv.select('polarization',-5,-5,include=True) for i in range(20): preamble, data = uv.read() idx, = data.nonzero() if len(idx) > len(good_idx): good_idx = copy.copy(idx) uv.select('clear',0,0) uv.rewind() if 'source' in uv.vartable: src = uv['source'] nf = len(good_idx) freq = uv['sfreq'][good_idx] npol = uv['npol'] nants = uv['nants'] nbl = nants*(nants-1)/2 bl2ord = p.bl_list(nants) if not tp_only: outa = np.zeros((nants,npol,nf,600),dtype=np.complex64) # Auto-correlations outx = np.zeros((nbl,npol,nf,600),dtype=np.complex64) # Cross-correlations outp = np.zeros((nants,2,nf,600),dtype=np.float) outp2 = np.zeros((nants,2,nf,600),dtype=np.float) outm = np.zeros((nants,2,nf,600),dtype=np.int) uvwarray = np.zeros((nbl,600,3),dtype=np.float) timearray = [] l = -1 tprev = 0 tsav = 0 # Use antennalist if available if 'antlist' in uv.vartable: ants = uv['antlist'] antlist = map(int, ants.split()) else: antlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] for preamble, data in uv.all(): uvw, t, (i0,j0) = preamble i = antlist.index(i0+1) j = antlist.index(j0+1) if i > j: # Reverse order of indices j = antlist.index(i0+1) i = antlist.index(j0+1) # Assumes uv['pol'] is one of -5, -6, -7, -8 k = -5 - uv['pol'] if filter: if len(data.nonzero()[0]) == nf: if t != tprev: # print preamble # New time l += 1 if l == 600: break tprev = t timearray.append(t) xdata = uv['xsampler'].reshape(500,nants,3) ydata = uv['ysampler'].reshape(500,nants,3) outp[:,0,:,l] = np.swapaxes(xdata[good_idx,:,0],0,1) outp[:,1,:,l] = np.swapaxes(ydata[good_idx,:,0],0,1) outp2[:,0,:,l] = np.swapaxes(xdata[good_idx,:,1],0,1) outp2[:,1,:,l] = np.swapaxes(ydata[good_idx,:,1],0,1) outm[:,0,:,l] = np.swapaxes(xdata[good_idx,:,2],0,1) outm[:,1,:,l] = np.swapaxes(ydata[good_idx,:,2],0,1) if tp_only: outa = None outx = None else: if i0 == j0: # This is an auto-correlation outa[i0,k,:,l] = data[data.nonzero()] else: outx[bl2ord[i,j],k,:,l] = data[data.nonzero()] if k == 3: uvwarray[bl2ord[i,j],l] = uvw[data.nonzero()] else: if t != tprev: # New time l += 1 if l == 600: break tprev = t timearray.append(t) xdata = uv['xsampler'].reshape(500,nants,3) ydata = uv['ysampler'].reshape(500,nants,3) outp[:,0,:,l] = np.swapaxes(xdata[:,:,0],0,1) outp[:,1,:,l] = np.swapaxes(ydata[:,:,0],0,1) outp2[:,0,:,l] = np.swapaxes(xdata[:,:,1],0,1) outp2[:,1,:,l] = np.swapaxes(ydata[:,:,1],0,1) outm[:,0,:,l] = np.swapaxes(xdata[:,:,2],0,1) outm[:,1,:,l] = np.swapaxes(ydata[:,:,2],0,1) if tp_only: outa = None outx = None else: if i0 == j0: # This is an auto-correlation outa[i0,k,:,l] = data if k < 2 and np.sum(data != np.real(data)) > 0: print preamble,uv['pol'], 'has imaginary data!' else: outx[bl2ord[i,j],k,:,l] = data if k == 3: uvwarray[bl2ord[i,j],l] = uvw # Truncate in case of early end of data nt = len(timearray) outp = outp[:,:,:,:nt] outp2 = outp2[:,:,:,:nt] outm = outm[:,:,:,:nt] outa = outa[:,:,:,:nt] outx = outx[:,:,:,:nt] out = {'a':outa, 'x':outx, 'uvw':uvwarray, 'fghz':freq, 'time':np.array(timearray),'source':src,'p':outp,'p2':outp2,'m':outm} return out
def readXdatmp(filename): # This temporary routine reads the data from a single IDBfile where the # polarization was written incorrectly. (-1,-2,0,0) instead of (-5,-6,-7,-8) # the IDB array sorts basline pairs into correct order for an output # array that just has 18 baselines (2 sets of 4 antennas correlated separately # now just need to convert i,j into slot in 136-slot array: 15*16/2 corrs +16 auto # this array corresponds to the first index (auto corr) for each antenna # 16*(iant-1)-(iant-1)(iant-2)/2 ibl = np.array( [ 0,16,31,45,58,70,81,91,100,108,115,121,126,130,133,135 ]) # Open uv file for reading uv = aipy.miriad.UV(filename) good_idx = [] # Read a bunch of records to get number of good frequencies, i.e. those with at least # some non-zero data. Read 20 records for baseline 1-2, XX pol uv.select('antennae',0,2,include=True) uv.select('polarization',-1,-1,include=True) for i in range(20): preamble, data = uv.read() idx, = data.nonzero() if len(idx) > len(good_idx): good_idx = copy.copy(idx) if 'source' in uv.vartable: src = uv['source'] uv.select('clear',0,0) uv.rewind() nf = len(good_idx) freq = uv['sfreq'][good_idx] npol = uv['npol'] nants = uv['nants'] nbl = nants*(nants-1)/2 bl2ord = p.bl_list(nants) outa = np.zeros((nants,npol,nf,600),dtype=np.complex64) # Auto-correlations outx = np.zeros((nbl,npol,nf,600),dtype=np.complex64) # Cross-correlations outp = np.zeros((nants,2,nf,600),dtype=np.float) outp2 = np.zeros((nants,2,nf,600),dtype=np.float) outm = np.zeros((nants,2,nf,600),dtype=np.int) uvwarray = [] timearray = [] l = -1 tprev = 0 # Use antennalist if available if 'antlist' in uv.vartable: ants = uv['antlist'] antlist = map(int, ants.split()) else: antlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] kp = 0 for preamble, data in uv.all(): uvw, t, (i0,j0) = preamble i = antlist.index(i0+1) j = antlist.index(j0+1) if i > j: # Reverse order of indices j = antlist.index(i0+1) i = antlist.index(j0+1) # Assumes uv['pol'] is -1, -2, 0, 0 if i == 0 and j == 0: if uv['pol'] == -1: k = 0 elif uv['pol'] == -2: k = 1 elif uv['pol'] == 0: if kp == 1: k = 2 kp = 0 else: k = 3 kp = 1 if k == 3: uvwarray.append(uvw) if len(data.nonzero()[0]) == nf: if t != tprev: # New time l += 1 if l == 600: break tprev = t timearray.append(t) xdata = uv['xsampler'].reshape(500,nants,3) ydata = uv['ysampler'].reshape(500,nants,3) outp[:,0,:,l] = np.swapaxes(xdata[good_idx,:,0],0,1) outp[:,1,:,l] = np.swapaxes(ydata[good_idx,:,0],0,1) outp2[:,0,:,l] = np.swapaxes(xdata[good_idx,:,1],0,1) outp2[:,1,:,l] = np.swapaxes(ydata[good_idx,:,1],0,1) outm[:,0,:,l] = np.swapaxes(xdata[good_idx,:,2],0,1) outm[:,1,:,l] = np.swapaxes(ydata[good_idx,:,2],0,1) if i0 == j0: # This is an auto-correlation outa[i0,k,:,l] = data[data.nonzero()] else: outx[bl2ord[i,j],k,:,l] = data[data.nonzero()] out = {'a':outa, 'x':outx, 'uvw':np.array(uvwarray), 'fghz':freq, 'time':np.array(timearray),'source':src,'p':outp,'p2':outp2,'m':outm} return out