Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
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
Ejemplo n.º 7
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)
    fpga_count = data.datasets['timestamp_fpga_count'][:]

    return data, Vis, ctime, RA, fpga_count
Ejemplo n.º 8
0
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_
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
def test_transit_RA():

    # transit RA is deprecated and should just throw an exception
    with pytest.raises(NotImplementedError):
        ephemeris.transit_RA(0.0)
Ejemplo n.º 11
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[:]
Ejemplo n.º 12
0
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])]
Ejemplo n.º 13
0
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_
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
    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