def print_timestamp(fn): src_dict = {'CasA': eph.CasA, 'TauA': eph.TauA, 'CygA': eph.CygA, 'VirA': eph.VirA, '1929': 292.0, '0329': 54.0} try: f = h5py.File(fn, 'r') except IOError: print "File couldn't be opened" return times = f['index_map']['time'].value['ctime'][:] print "-------------------------------------" print "start time %s in PT\n" % (eph.unix_to_datetime(times[0])) print "RA range %f : %f" % (np.round(eph.transit_RA(times[0]), 1), np.round(eph.transit_RA(times[-1]),1)) print "-------------------------------------" srcz = [] for src in src_dict: if eph.transit_times(src_dict[src], times[0])[0] < times[-1]: print "%s is in this file" % src srcz.append(src) return srcz
def fs_from_file(filename, frq, src, del_t=900, transposed=True, subtract_avg=False): f = h5py.File(filename, 'r') times = f['index_map']['time'].value['ctime'] + 10.6 src_trans = eph.transit_times(src, times[0]) # try to account for differential arrival time from cylinder rotation. del_phi = (src._dec - np.radians(eph.CHIMELATITUDE)) * np.sin(np.radians(1.988)) del_phi *= (24 * 3600.0) / (2 * np.pi) # Adjust the transit time accordingly src_trans += del_phi # Select +- del_t of transit, accounting for the mispointing t_range = np.where((times < src_trans + del_t) & (times > src_trans - del_t))[0] times = times[t_range[0]:t_range[-1]]#[offp::2] test print "Time range:", times[0], times[-1] print "\n...... This data is from %s starting at RA: %f ...... \n" \ % (eph.unix_to_datetime(times[0]), eph.transit_RA(times[0])) if transposed is True: v = f['vis'][frq[0]:frq[-1]+1, :] v = v[..., t_range[0]:t_range[-1]] vis = v['r'] + 1j * v['i'] del v # Read in time and freq slice if data has not yet been transposed if transposed is False: v = f['vis'][t_range[0]:t_range[-1], frq[0]:frq[-1]+1, :] vis = v['r'][:] + 1j * v['i'][:] del v vis = np.transpose(vis, (1, 2, 0)) inp = gen_inp()[0] # Remove offset from galaxy if subtract_avg is True: vis -= 0.5 * (vis[..., 0] + vis[..., -1])[..., np.newaxis] freq_MHZ = 800.0 - np.array(frq) / 1024.0 * 400. print len(inp) baddies = np.where(np.isnan(tools.get_feed_positions(inp)[:, 0]))[0] # Fringestop to location of "src" data_fs = tools.fringestop_pathfinder(vis, eph.transit_RA(times), freq_MHZ, inp, src) # data_fs = fringestop_pathfinder(vis, eph.transit_RA(times), freq_MHZ, inp, src) return data_fs
def print_timestamp(fn): src_dict = { 'CasA': eph.CasA, 'TauA': eph.TauA, 'CygA': eph.CygA, 'VirA': eph.VirA, '1929': 292.0, '0329': 54.0 } try: f = h5py.File(fn, 'r') except IOError: print "File couldn't be opened" return times = f['index_map']['time'].value['ctime'][:] print "-------------------------------------" print "start time %s in PT\n" % (eph.unix_to_datetime(times[0])) print "RA range %f : %f" % (np.round(eph.transit_RA( times[0]), 1), np.round(eph.transit_RA(times[-1]), 1)) print "-------------------------------------" srcz = [] for src in src_dict: if eph.transit_times(src_dict[src], times[0])[0] < times[-1]: print "%s is in this file" % src srcz.append(src) return srcz
def drao_aro_RA(times): """ Go from DRAO transit RA to ARO transit RA """ RA_trans = eph.transit_RA(times) long_diff = AROLONGITUDE - eph.CHIMELONGITUDE return RA_trans + long_diff
def test_drao_aro_RA(self): times = self.times diff_true = np.round(np.mod(eph.CHIMELONGITUDE - (-78.0730), 360)) DRAO_RA_trans = eph.transit_RA(times) ARO_RA_trans = pv.drao_aro_RA(times) diff = np.round(np.mod(DRAO_RA_trans - ARO_RA_trans, 360).mean()) assert diff == diff_true assert np.round(np.std(diff), 2)==0.0
def get_data(file, start=False, stop=False): if not start and not stop: data = chand.from_acq_h5(file) else: data = chand.from_acq_h5(file, start=start, stop=stop) Vis = data.vis print "vis shape:", Vis.shape ctime = data.timestamp if np.isnan(ctime).sum() > 0: print "Removing NaNs" Vis[:, :, ctime != ctime] = 0.0 ctime[ctime != ctime] = 0.0 RA = eph.transit_RA(ctime) return data, Vis, ctime, RA
def get_data(file, start=False, stop=False): if not start and not stop: data = chand.from_acq_h5(file) else: data = chand.from_acq_h5(file, start=start, stop=stop) Vis = data.vis print "vis shape:", Vis.shape ctime = data.timestamp if np.isnan(ctime).sum() > 0: print "Removing NaNs" Vis[:, :, ctime != ctime] = 0.0 ctime[ctime != ctime] = 0.0 RA = eph.transit_RA(ctime) fpga_count = data.datasets['timestamp_fpga_count'][:] return data, Vis, ctime, RA, fpga_count
def fringestop_and_sum(fn, feeds, freq, src, transposed=True, return_unfs=True, meridian=False, del_t=1500, frick=None): """ Take an input file fn and a set of feeds and return a formed beam on src. """ if transposed is True: r = andata.Reader(fn) r.freq_sel = freq X = r.read() times = r.time else: f = h5py.File(fn, 'r') times = f['index_map']['time'].value['ctime'] print "Read in data" # Get transit time for source src_trans = eph.transit_times(src, times[0]) del_phi = 1.30 * (src._dec - np.radians(eph.CHIMELATITUDE)) * np.sin(np.radians(1.988)) del_phi *= (24 * 3600.0) / (2 * np.pi) # Adjust the transit time accordingly src_trans += del_phi # Select +- del_t of transit, accounting for the mispointing t_range = np.where((times < src_trans + del_t) & (times > src_trans - del_t))[0] times = times[t_range[0]:t_range[-1]]#[offp::2] test print "Time range:", times[0], times[-1] # Generate correctly ordered corrinputs corrinput_real = gen_inp()[0] inp = np.array(corrinput_real) # Ensure vis array is in correct order (freq, prod, time) if transposed is True: data = X.vis[:, :, t_range[0]:t_range[-1]] freq = X.freq else: v = f['vis'][t_range[0]:t_range[-1], freq, :] vis = v['r'] + 1j * v['i'] data = vis.transpose()[np.newaxis] del vis freq = 800 - 400.0 / 1024 * freq freq = np.array([freq]) # autos = auto_corrs(256) # offp = (abs(data[:, autos, 0::2]).mean() > (abs(data[:, autos, 1::2]).mean())).astype(int) # data = data[..., offp::2] test data_unfs = sum_corrs(data.copy(), feeds) ra_ = eph.transit_RA(times) ra_2 = nolan_ra(times) #ra_ = ra_2.copy() if meridian is True: ra = np.ones_like(ra_) * np.degrees(src._ra) else: ra = ra_ print len(inp) dfs = tools.fringestop_pathfinder(data.copy(), ra, freq, inp, src) #dfs = fringestop_pathfinder(data.copy(), ra_2, freq, inp, src, frick=frick) # dfs = fringestop_pathfinder(data.copy(), ra_1, freq, inp, src, frick=frick) # fp = np.loadtxt('/home/connor/feed_layout_decrease.txt') # PH = fill_nolan(times, src._ra * 180.0 / np.pi, src._dec * 180.0 / np.pi, fp) dfs_sum = sum_corrs(dfs, feeds) if return_unfs is True: return dfs_sum, ra_, dfs, data else: return dfs_sum, ra_
def solve_ps_transit(filename, corrs, feeds, inp, src, nfreq=1024, transposed=False, nfeed=128): """ Function that fringestops time slice where point source is in the beam, takes all correlations for a given polarization, and then eigendecomposes the correlation matrix freq by freq after removing the fpga phases. It will also plot intermediate steps to verify the phase solution. Parameters ---------- filename : np.str Full-path filename corrs : list List of correlations to use in solver feeds : list List of feeds to use inp : Correlator inputs (output of ch_util.tools.get_correlator_inputs) src : ephem.FixedBody Source to calibrate off of. e.g. ch_util.ephemeris.TauA Returns ------- Gains : np.array Complex gain array (nfreq, nfeed) """ nsplit = 32 # Number of freq chunks to divide nfreq into del_t = 800 f = h5py.File(filename, 'r') # Add half an integration time to each. Hack. times = f['index_map']['time'].value['ctime'] + 10.50 src_trans = eph.transit_times(src, times[0]) # try to account for differential arrival time from # cylinder rotation. del_phi = (src._dec - np.radians(eph.CHIMELATITUDE)) \ * np.sin(np.radians(1.988)) del_phi *= (24 * 3600.0) / (2 * np.pi) # Adjust the transit time accordingly src_trans += del_phi # Select +- del_t of transit, accounting for the mispointing t_range = np.where((times < src_trans + del_t) & (times > src_trans - del_t))[0] print "\n...... This data is from %s starting at RA: %f ...... \n" \ % (eph.unix_to_datetime(times[0]), eph.transit_RA(times[0])) assert (len(t_range) > 0), "Source is not in this acq" # Create gains array to fill in solution Gains = np.zeros([nfreq, nfeed], np.complex128) print "Starting the solver" times = times[t_range[0]:t_range[-1]] k=0 # Start at a strong freq channel that can be plotted # and from which we can find the noise source on-sample for i in range(12, nsplit) + range(0, 12): k+=1 # Divides the arrays up into nfreq / nsplit freq chunks and solves those frq = range(i * nfreq // nsplit, (i+1) * nfreq // nsplit) print " %d:%d \n" % (frq[0], frq[-1]) # Read in time and freq slice if data has already been transposed if transposed is True: v = f['vis'][frq[0]:frq[-1]+1, corrs, :] v = v[..., t_range[0]:t_range[-1]] vis = v['r'] + 1j * v['i'] if k==1: autos = auto_corrs(nfeed) offp = (abs(vis[:, autos, 0::2]).mean() > \ (abs(vis[:, autos, 1::2]).mean())).astype(int) times = times[offp::2] vis = vis[..., offp::2] gg = f['gain_coeff'][frq[0]:frq[-1]+1, feeds, t_range[0]:t_range[-1]][..., offp::2] gain_coeff = gg['r'] + 1j * gg['i'] del gg # Read in time and freq slice if data has not yet been transposed if transposed is False: print "TRANSPOSED V OF CODE DOESN'T WORK YET!" v = f['vis'][t_range[0]:t_range[-1]:2, frq[0]:frq[-1]+1, corrs] vis = v['r'][:] + 1j * v['i'][:] del v gg = f['gain_coeff'][0, frq[0]:frq[-1]+1, feeds] gain_coeff = gg['r'][:] + 1j * gg['i'][:] vis = vis[..., offp::2] vis = np.transpose(vis, (1, 2, 0)) # Remove fpga gains from data vis = remove_fpga_gains(vis, gain_coeff, nfeed=nfeed, triu=False) # Remove offset from galaxy vis -= 0.5 * (vis[..., 0] + vis[..., -1])[..., np.newaxis] # Get physical freq for fringestopper freq_MHZ = 800.0 - np.array(frq) / 1024.0 * 400. baddies = np.where(np.isnan(tools.get_feed_positions(inp)[:, 0]))[0] a, b, c = select_corrs(baddies, nfeed=128) vis[:, a + b] = 0.0 # Fringestop to location of "src" data_fs = tools.fringestop_pathfinder(vis, eph.transit_RA(times), freq_MHZ, inp, src) del vis dr, sol_arr = solve_gain(data_fs) # Find index of point source transit drlist = np.argmax(dr, axis=-1) # If multiple freq channels are zerod, the trans_pix # will end up being 0. This is bad, so ensure that # you are only looking for non-zero transit pixels. drlist = [x for x in drlist if x != 0] trans_pix = np.argmax(np.bincount(drlist)) assert trans_pix != 0.0 Gains[frq] = sol_arr[..., trans_pix-3:trans_pix+4].mean(-1) zz = h5py.File('data' + str(i) + '.hdf5','w') zz.create_dataset('data', data=dr) zz.close() print "%f, %d Nans out of %d" % (np.isnan(sol_arr).sum(), np.isnan(Gains[frq]).sum(), np.isnan(Gains[frq]).sum()) print trans_pix, sol_arr[..., trans_pix-3:trans_pix+4].mean(-1).sum(), sol_arr.mean(-1).sum() # Plot up post-fs phases to see if everything has been fixed if frq[0] == 12 * nsplit: print "======================" print " Plotting up freq: %d" % frq[0] print "======================" img_nm = './phs_plots/dfs' + np.str(frq[17]) + np.str(np.int(time.time())) +'.png' img_nmcorr = './phs_plots/dfs' + np.str(frq[17]) + np.str(np.int(time.time())) +'corr.png' plt_gains(data_fs, 0, img_name=img_nm, bad_chans=baddies) dfs_corr = correct_dfs(data_fs, np.angle(Gains[frq])[..., np.newaxis], nfeed=128) plt_gains(dfs_corr, 0, img_name=img_nmcorr, bad_chans=baddies) del dfs_corr del data_fs, a return Gains
def test_transit_RA(): # transit RA is deprecated and should just throw an exception with pytest.raises(NotImplementedError): ephemeris.transit_RA(0.0)
elif on_gate > 9: on_vis = 0.80 * arr_corr[..., on_gate] + \ 0.10 * (arr_corr[..., on_gate+1] + arr_corr[..., on_gate-1]) off_vis = 0.5 * (arr_corr[..., on_gate-3] + \ arr_corr[..., on_gate+3]) psr_vis = on_vis - off_vis x = 7 y = 3 print psr_vis.shape, time.shape RC = chp.PulsarPipeline(psr_vis[:, np.newaxis], time) RC.RA_src, RC.dec = 53.51337, 54.6248916 RC.ln = args.ln RC.RA = eph.transit_RA(time) RC.corrs = corrs[rank] RC.fringestop() psr_vis = RC.data[:, 0] print "0" psr_vis = misc.correct_delay(psr_vis, nfreq=nfreq) print "1" if args.svd == 1: psr_vis_cal = misc.svd_model(psr_vis, phase_only=True) print "Performing SVD on dynamic spectrum, rank %d" % rank else: print "Skipping SVD" psr_vis_cal = psr_vis[:]
its.") parser.add_argument("Data", help="Directory containing acquisition files.") parser.add_argument("--Objects", help="Celestial objects to fit", default='All') parser.add_argument("--minfile", help="Minfile number e.g. 0051", default="") parser.add_argument("--maxfile", help="Maxfile number e.g. 0051", default="") args = parser.parse_args() files = np.str(args.Data) + '*h5.' + args.maxfile + '*' print "" print "Reading in Data:", files Data, vis, utime, RA = misc.get_data(files) print "RA range of data:", RA.min(),":",RA.max() RA_sun = eph.transit_RA(eph.solar_transit(utime[0])) sun_RA_low = RA_sun - 6 sun_RA_high = RA_sun + 6 print "" print "Das sun was at: %f" % RA_sun # Create a dictionary with each fitting object's information in the form: {"Obj": [RA_min, RA_max, Declination]}. celestial_object = { "CasA": [344, 358, 58.83], "TauA": [77, 87, 83.6], "CygA": [297, 302, 40.73], "Sun": [sun_RA_low, sun_RA_high, 0]} if args.Objects != "All": srcs2fit = [args.Objects] else: srcs2fit = celestial_object.keys() for src in srcs2fit: vis_obj = vis[:, :, ( RA > celestial_object[src][0] ) & ( RA < celestial_object[src][1])]
def fringestop_and_sum(fn, feeds, freq, src, transposed=True, return_unfs=True, meridian=False, del_t=1500, frick=None): """ Take an input file fn and a set of feeds and return a formed beam on src. """ if transposed is True: r = andata.Reader(fn) r.freq_sel = freq X = r.read() times = r.time else: f = h5py.File(fn, 'r') times = f['index_map']['time'].value['ctime'] print "Read in data" # Get transit time for source src_trans = eph.transit_times(src, times[0]) del_phi = 1.30 * (src._dec - np.radians(eph.CHIMELATITUDE)) * np.sin( np.radians(1.988)) del_phi *= (24 * 3600.0) / (2 * np.pi) # Adjust the transit time accordingly src_trans += del_phi # Select +- del_t of transit, accounting for the mispointing t_range = np.where((times < src_trans + del_t) & (times > src_trans - del_t))[0] times = times[t_range[0]:t_range[-1]] #[offp::2] test print "Time range:", times[0], times[-1] # Generate correctly ordered corrinputs corrinput_real = gen_inp()[0] inp = np.array(corrinput_real) # Ensure vis array is in correct order (freq, prod, time) if transposed is True: data = X.vis[:, :, t_range[0]:t_range[-1]] freq = X.freq else: v = f['vis'][t_range[0]:t_range[-1], freq, :] vis = v['r'] + 1j * v['i'] data = vis.transpose()[np.newaxis] del vis freq = 800 - 400.0 / 1024 * freq freq = np.array([freq]) # autos = auto_corrs(256) # offp = (abs(data[:, autos, 0::2]).mean() > (abs(data[:, autos, 1::2]).mean())).astype(int) # data = data[..., offp::2] test data_unfs = sum_corrs(data.copy(), feeds) ra_ = eph.transit_RA(times) ra_2 = nolan_ra(times) #ra_ = ra_2.copy() if meridian is True: ra = np.ones_like(ra_) * np.degrees(src._ra) else: ra = ra_ print len(inp) dfs = tools.fringestop_pathfinder(data.copy(), ra, freq, inp, src) #dfs = fringestop_pathfinder(data.copy(), ra_2, freq, inp, src, frick=frick) # dfs = fringestop_pathfinder(data.copy(), ra_1, freq, inp, src, frick=frick) # fp = np.loadtxt('/home/connor/feed_layout_decrease.txt') # PH = fill_nolan(times, src._ra * 180.0 / np.pi, src._dec * 180.0 / np.pi, fp) dfs_sum = sum_corrs(dfs, feeds) if return_unfs is True: return dfs_sum, ra_, dfs, data else: return dfs_sum, ra_
def fs_from_file(filename, frq, src, del_t=900, transposed=True, subtract_avg=False): f = h5py.File(filename, 'r') times = f['index_map']['time'].value['ctime'] + 10.6 src_trans = eph.transit_times(src, times[0]) # try to account for differential arrival time from cylinder rotation. del_phi = (src._dec - np.radians(eph.CHIMELATITUDE)) * np.sin( np.radians(1.988)) del_phi *= (24 * 3600.0) / (2 * np.pi) # Adjust the transit time accordingly src_trans += del_phi # Select +- del_t of transit, accounting for the mispointing t_range = np.where((times < src_trans + del_t) & (times > src_trans - del_t))[0] times = times[t_range[0]:t_range[-1]] #[offp::2] test print "Time range:", times[0], times[-1] print "\n...... This data is from %s starting at RA: %f ...... \n" \ % (eph.unix_to_datetime(times[0]), eph.transit_RA(times[0])) if transposed is True: v = f['vis'][frq[0]:frq[-1] + 1, :] v = v[..., t_range[0]:t_range[-1]] vis = v['r'] + 1j * v['i'] del v # Read in time and freq slice if data has not yet been transposed if transposed is False: v = f['vis'][t_range[0]:t_range[-1], frq[0]:frq[-1] + 1, :] vis = v['r'][:] + 1j * v['i'][:] del v vis = np.transpose(vis, (1, 2, 0)) inp = gen_inp()[0] # Remove offset from galaxy if subtract_avg is True: vis -= 0.5 * (vis[..., 0] + vis[..., -1])[..., np.newaxis] freq_MHZ = 800.0 - np.array(frq) / 1024.0 * 400. print len(inp) baddies = np.where(np.isnan(tools.get_feed_positions(inp)[:, 0]))[0] # Fringestop to location of "src" data_fs = tools.fringestop_pathfinder(vis, eph.transit_RA(times), freq_MHZ, inp, src) # data_fs = fringestop_pathfinder(vis, eph.transit_RA(times), freq_MHZ, inp, src) return data_fs
def solve_ps_transit(filename, corrs, feeds, inp, src, nfreq=1024, transposed=False, nfeed=128): """ Function that fringestops time slice where point source is in the beam, takes all correlations for a given polarization, and then eigendecomposes the correlation matrix freq by freq after removing the fpga phases. It will also plot intermediate steps to verify the phase solution. Parameters ---------- filename : np.str Full-path filename corrs : list List of correlations to use in solver feeds : list List of feeds to use inp : Correlator inputs (output of ch_util.tools.get_correlator_inputs) src : ephem.FixedBody Source to calibrate off of. e.g. ch_util.ephemeris.TauA Returns ------- Gains : np.array Complex gain array (nfreq, nfeed) """ nsplit = 32 # Number of freq chunks to divide nfreq into del_t = 800 f = h5py.File(filename, 'r') # Add half an integration time to each. Hack. times = f['index_map']['time'].value['ctime'] + 10.50 src_trans = eph.transit_times(src, times[0]) # try to account for differential arrival time from # cylinder rotation. del_phi = (src._dec - np.radians(eph.CHIMELATITUDE)) \ * np.sin(np.radians(1.988)) del_phi *= (24 * 3600.0) / (2 * np.pi) # Adjust the transit time accordingly src_trans += del_phi # Select +- del_t of transit, accounting for the mispointing t_range = np.where((times < src_trans + del_t) & (times > src_trans - del_t))[0] print "\n...... This data is from %s starting at RA: %f ...... \n" \ % (eph.unix_to_datetime(times[0]), eph.transit_RA(times[0])) assert (len(t_range) > 0), "Source is not in this acq" # Create gains array to fill in solution Gains = np.zeros([nfreq, nfeed], np.complex128) print "Starting the solver" times = times[t_range[0]:t_range[-1]] k = 0 # Start at a strong freq channel that can be plotted # and from which we can find the noise source on-sample for i in range(12, nsplit) + range(0, 12): k += 1 # Divides the arrays up into nfreq / nsplit freq chunks and solves those frq = range(i * nfreq // nsplit, (i + 1) * nfreq // nsplit) print " %d:%d \n" % (frq[0], frq[-1]) # Read in time and freq slice if data has already been transposed if transposed is True: v = f['vis'][frq[0]:frq[-1] + 1, corrs, :] v = v[..., t_range[0]:t_range[-1]] vis = v['r'] + 1j * v['i'] if k == 1: autos = auto_corrs(nfeed) offp = (abs(vis[:, autos, 0::2]).mean() > \ (abs(vis[:, autos, 1::2]).mean())).astype(int) times = times[offp::2] vis = vis[..., offp::2] gg = f['gain_coeff'][frq[0]:frq[-1] + 1, feeds, t_range[0]:t_range[-1]][..., offp::2] gain_coeff = gg['r'] + 1j * gg['i'] del gg # Read in time and freq slice if data has not yet been transposed if transposed is False: print "TRANSPOSED V OF CODE DOESN'T WORK YET!" v = f['vis'][t_range[0]:t_range[-1]:2, frq[0]:frq[-1] + 1, corrs] vis = v['r'][:] + 1j * v['i'][:] del v gg = f['gain_coeff'][0, frq[0]:frq[-1] + 1, feeds] gain_coeff = gg['r'][:] + 1j * gg['i'][:] vis = vis[..., offp::2] vis = np.transpose(vis, (1, 2, 0)) # Remove fpga gains from data vis = remove_fpga_gains(vis, gain_coeff, nfeed=nfeed, triu=False) # Remove offset from galaxy vis -= 0.5 * (vis[..., 0] + vis[..., -1])[..., np.newaxis] # Get physical freq for fringestopper freq_MHZ = 800.0 - np.array(frq) / 1024.0 * 400. baddies = np.where(np.isnan(tools.get_feed_positions(inp)[:, 0]))[0] a, b, c = select_corrs(baddies, nfeed=128) vis[:, a + b] = 0.0 # Fringestop to location of "src" data_fs = tools.fringestop_pathfinder(vis, eph.transit_RA(times), freq_MHZ, inp, src) del vis dr, sol_arr = solve_gain(data_fs) # Find index of point source transit drlist = np.argmax(dr, axis=-1) # If multiple freq channels are zerod, the trans_pix # will end up being 0. This is bad, so ensure that # you are only looking for non-zero transit pixels. drlist = [x for x in drlist if x != 0] trans_pix = np.argmax(np.bincount(drlist)) assert trans_pix != 0.0 Gains[frq] = sol_arr[..., trans_pix - 3:trans_pix + 4].mean(-1) zz = h5py.File('data' + str(i) + '.hdf5', 'w') zz.create_dataset('data', data=dr) zz.close() print "%f, %d Nans out of %d" % (np.isnan(sol_arr).sum(), np.isnan(Gains[frq]).sum(), np.isnan(Gains[frq]).sum()) print trans_pix, sol_arr[..., trans_pix - 3:trans_pix + 4].mean(-1).sum(), sol_arr.mean(-1).sum() # Plot up post-fs phases to see if everything has been fixed if frq[0] == 12 * nsplit: print "======================" print " Plotting up freq: %d" % frq[0] print "======================" img_nm = './phs_plots/dfs' + np.str(frq[17]) + np.str( np.int(time.time())) + '.png' img_nmcorr = './phs_plots/dfs' + np.str(frq[17]) + np.str( np.int(time.time())) + 'corr.png' plt_gains(data_fs, 0, img_name=img_nm, bad_chans=baddies) dfs_corr = correct_dfs(data_fs, np.angle(Gains[frq])[..., np.newaxis], nfeed=128) plt_gains(dfs_corr, 0, img_name=img_nmcorr, bad_chans=baddies) del dfs_corr del data_fs, a return Gains
def process(self, sstream, inputmap, inputmask): """Determine calibration from a timestream. Parameters ---------- sstream : andata.CorrData or containers.SiderealStream Timestream collected during the day. inputmap : list of :class:`CorrInput` A list describing the inputs as they are in the file. inputmask : containers.CorrInputMask Mask indicating which correlator inputs to use in the eigenvalue decomposition. Returns ------- suntrans : containers.SunTransit Response to the sun. """ from operator import itemgetter from itertools import groupby from .calibration import _extract_diagonal, solve_gain # Ensure that we are distributed over frequency sstream.redistribute("freq") # Find the local frequencies nfreq = sstream.vis.local_shape[0] sfreq = sstream.vis.local_offset[0] efreq = sfreq + nfreq # Get the local frequency axis freq = sstream.freq["centre"][sfreq:efreq] wv = 3e2 / freq # Get times if hasattr(sstream, "time"): time = sstream.time ra = ephemeris.transit_RA(time) else: ra = sstream.index_map["ra"][:] csd = (sstream.attrs["lsd"] if "lsd" in sstream.attrs else sstream.attrs["csd"]) csd = csd + ra / 360.0 time = ephemeris.csd_to_unix(csd) # Only examine data between sunrise and sunset time_flag = np.zeros(len(time), dtype=np.bool) rise = ephemeris.solar_rising(time[0] - 24.0 * 3600.0, end_time=time[-1]) for rr in rise: ss = ephemeris.solar_setting(rr)[0] time_flag |= (time >= rr) & (time <= ss) if not np.any(time_flag): self.log.debug( "No daytime data between %s and %s.", ephemeris.unix_to_datetime(time[0]).strftime("%b %d %H:%M"), ephemeris.unix_to_datetime(time[-1]).strftime("%b %d %H:%M"), ) return None # Convert boolean flag to slices time_index = np.where(time_flag)[0] time_slice = [] ntime = 0 for key, group in groupby( enumerate(time_index), lambda index_item: index_item[0] - index_item[1]): group = list(map(itemgetter(1), group)) ngroup = len(group) time_slice.append( (slice(group[0], group[-1] + 1), slice(ntime, ntime + ngroup))) ntime += ngroup time = np.concatenate([time[slc[0]] for slc in time_slice]) ra = np.concatenate([ra[slc[0]] for slc in time_slice]) # Get ra, dec, alt of sun sun_pos = np.array([ ra_dec_of(ephemeris.skyfield_wrapper.ephemeris["sun"], t) for t in time ]) # Convert from ra to hour angle sun_pos[:, 0] = np.radians(ra) - sun_pos[:, 0] # Determine good inputs nfeed = len(inputmap) good_input = np.arange( nfeed, dtype=np.int)[inputmask.datasets["input_mask"][:]] # Use input map to figure out which are the X and Y feeds xfeeds = np.array([ idx for idx, inp in enumerate(inputmap) if tools.is_chime_x(inp) and (idx in good_input) ]) yfeeds = np.array([ idx for idx, inp in enumerate(inputmap) if tools.is_chime_y(inp) and (idx in good_input) ]) self.log.debug( "Performing sun calibration with %d/%d good feeds (%d xpol, %d ypol).", len(good_input), nfeed, len(xfeeds), len(yfeeds), ) # Construct baseline vector for each visibility feed_pos = tools.get_feed_positions(inputmap) vis_pos = np.array([ feed_pos[ii] - feed_pos[ij] for ii, ij in sstream.index_map["prod"][:] ]) vis_pos = np.where(np.isnan(vis_pos), np.zeros_like(vis_pos), vis_pos) u = (vis_pos[np.newaxis, :, 0] / wv[:, np.newaxis])[:, :, np.newaxis] v = (vis_pos[np.newaxis, :, 1] / wv[:, np.newaxis])[:, :, np.newaxis] # Create container to hold results of fit suntrans = containers.SunTransit(time=time, pol_x=xfeeds, pol_y=yfeeds, axes_from=sstream) for key in suntrans.datasets.keys(): suntrans.datasets[key][:] = 0.0 # Set coordinates suntrans.coord[:] = sun_pos # Loop over time slices for slc_in, slc_out in time_slice: # Extract visibility slice vis_slice = sstream.vis[..., slc_in].copy() ha = (sun_pos[slc_out, 0])[np.newaxis, np.newaxis, :] dec = (sun_pos[slc_out, 1])[np.newaxis, np.newaxis, :] # Extract the diagonal (to be used for weighting) norm = (_extract_diagonal(vis_slice, axis=1).real)**0.5 norm = tools.invert_no_zero(norm) # Fringestop if self.fringestop: vis_slice *= tools.fringestop_phase( ha, np.radians(ephemeris.CHIMELATITUDE), dec, u, v) # Solve for the point source response of each set of polarisations ev_x, resp_x, err_resp_x = solve_gain(vis_slice, feeds=xfeeds, norm=norm[:, xfeeds]) ev_y, resp_y, err_resp_y = solve_gain(vis_slice, feeds=yfeeds, norm=norm[:, yfeeds]) # Save to container suntrans.evalue_x[..., slc_out] = ev_x suntrans.evalue_y[..., slc_out] = ev_y suntrans.response[:, xfeeds, slc_out] = resp_x suntrans.response[:, yfeeds, slc_out] = resp_y suntrans.response_error[:, xfeeds, slc_out] = err_resp_x suntrans.response_error[:, yfeeds, slc_out] = err_resp_y # If requested, fit a model to the primary beam of the sun transit if self.model_fit: # Estimate peak RA i_transit = np.argmin(np.abs(sun_pos[:, 0])) body = ephemeris.skyfield_wrapper.ephemeris["sun"] obs = ephemeris._get_chime() obs.date = ephemeris.unix_to_ephem_time(time[i_transit]) body.compute(obs) peak_ra = ephemeris.peak_RA(body) dra = ra - peak_ra dra = np.abs(dra - (dra > np.pi) * 2.0 * np.pi)[np.newaxis, np.newaxis, :] # Estimate FWHM sig_x = cal_utils.guess_fwhm(freq, pol="X", dec=body.dec, sigma=True)[:, np.newaxis, np.newaxis] sig_y = cal_utils.guess_fwhm(freq, pol="Y", dec=body.dec, sigma=True)[:, np.newaxis, np.newaxis] # Only fit ra values above the specified dynamic range threshold fit_flag = np.zeros([nfreq, nfeed, ntime], dtype=np.bool) fit_flag[:, xfeeds, :] = dra < (self.nsig * sig_x) fit_flag[:, yfeeds, :] = dra < (self.nsig * sig_y) # Fit model for the complex response of each feed to the point source param, param_cov = cal_utils.fit_point_source_transit( ra, suntrans.response[:], suntrans.response_error[:], flag=fit_flag) # Save to container suntrans.add_dataset("flag") suntrans.flag[:] = fit_flag suntrans.add_dataset("parameter") suntrans.parameter[:] = param suntrans.add_dataset("parameter_cov") suntrans.parameter_cov[:] = param_cov # Update attributes units = "sqrt(" + sstream.vis.attrs.get("units", "correlator-units") + ")" suntrans.response.attrs["units"] = units suntrans.response_error.attrs["units"] = units suntrans.attrs["source"] = "Sun" # Return sun transit return suntrans