Beispiel #1
0
 def impl(sigma_n,
          sigma_f,
          n_time,
          n_chan,
          n_ant,
          n_dir,
          corr_shape,
          jones_shape,
          phase_only_gains=False):
     rs = np.random.RandomState(42)
     n_bl = n_ant * (n_ant - 1) // 2
     n_row = n_bl * n_time
     # make aux data
     antenna1 = np.zeros(n_row, dtype=np.int16)
     antenna2 = np.zeros(n_row, dtype=np.int16)
     time = np.zeros(n_row, dtype=np.float64)
     uvw = np.zeros((n_row, 3), dtype=np.float64)
     time_values = np.linspace(0, 1, n_time)
     freq = np.linspace(1e9, 2e9, n_chan)
     for i in range(n_time):
         row = 0
         for p in range(n_ant):
             for q in range(p):
                 time[i * n_bl + row] = time_values[i]
                 antenna1[i * n_bl + row] = p
                 antenna2[i * n_bl + row] = q
                 uvw[i * n_bl + row] = np.random.randn(3)
                 row += 1
     assert time.size == n_row
     # simulate visibilities
     model_data = np.zeros((n_row, n_chan, n_dir) + corr_shape,
                           dtype=np.complex128)
     # make up some sources
     lm = lm_factory(n_dir, rs)
     alpha = -0.7
     freq0 = freq[n_chan // 2]
     flux = flux_factory(n_dir, n_chan, corr_shape, alpha, freq, freq0, rs)
     # simulate model data
     for dir in range(n_dir):
         dir_lm = lm[dir].reshape(1, 2)
         # Get flux for source (keep source axis, flatten cor axis)
         dir_flux = flux[dir].reshape(1, n_chan, np.prod(corr_shape))
         tmp = im_to_vis(dir_flux, uvw, dir_lm, freq)
         model_data[:, :, dir] = tmp.reshape((n_row, n_chan) + corr_shape)
     assert not np.isnan(model_data).any()
     # simulate gains (just randomly scattered around 1 for now)
     jones = np.ones((n_time, n_ant, n_chan, n_dir) + jones_shape,
                     dtype=np.complex128)
     if sigma_f:
         if phase_only_gains:
             jones = np.exp(
                 1.0j * rs.normal(loc=0.0, scale=sigma_f, size=jones.shape))
         else:
             jones += (
                 rs.normal(loc=0.0, scale=sigma_f, size=jones.shape) +
                 1.0j * rs.normal(loc=0.0, scale=sigma_f, size=jones.shape))
         assert (np.abs(jones) > 1e-5).all()
         assert not np.isnan(jones).any()
     # get vis
     _, time_bin_indices, time_bin_counts = chunkify_rows(time, n_time)
     vis = corrupt_vis(time_bin_indices, time_bin_counts, antenna1,
                       antenna2, jones, model_data)
     assert not np.isnan(vis).any()
     # add noise
     if sigma_n:
         vis += (rs.normal(loc=0.0, scale=sigma_n, size=vis.shape) +
                 1.0j * rs.normal(loc=0.0, scale=sigma_n, size=vis.shape))
     weights = np.ones(vis.shape, dtype=np.float64)
     if sigma_n:
         weights /= sigma_n**2
     flag = np.zeros(vis.shape, dtype=np.bool)
     data_dict = {}
     data_dict["DATA"] = vis
     data_dict["MODEL_DATA"] = model_data
     data_dict["WEIGHT_SPECTRUM"] = weights
     data_dict["TIME"] = time
     data_dict["ANTENNA1"] = antenna1
     data_dict["ANTENNA2"] = antenna2
     data_dict["FLAG"] = flag
     data_dict['JONES'] = jones
     return data_dict
Beispiel #2
0
def make_dual_pol_data(sigma_n, n_dir, sigma_f):
    # make aux data
    antenna1 = np.zeros(n_row, dtype=np.int16)
    antenna2 = np.zeros(n_row, dtype=np.int16)
    time = np.zeros(n_row, dtype=np.float32)
    uvw = np.zeros((n_row, 3), dtype=np.float32)
    unique_time = np.linspace(0, 1, n_time)
    freq = np.linspace(1e9, 2e9, n_chan)
    for i in range(n_time):
        row = 0
        for p in range(n_ant):
            for q in range(p):
                time[i * n_bl + row] = unique_time[i]
                antenna1[i * n_bl + row] = p
                antenna2[i * n_bl + row] = q
                uvw[i * n_bl + row] = np.random.randn(3)
                row += 1
    assert time.size == n_row
    # simulate visibilities
    model_data = np.zeros((n_row, n_chan, n_dir, n_cor), dtype=np.complex64)
    # make up some sources
    lm = give_lm(n_dir)
    flux = give_flux(n_dir)
    # simulate model data (pure Stokes I)
    for dir in range(n_dir):
        this_lm = lm[dir].reshape(1, 2)
        this_flux = np.tile(flux[dir], (n_chan, n_cor))[None, :, :]
        model_tmp = im_to_vis(this_flux, uvw, this_lm, freq)
        model_data[:, :, dir, :] = model_tmp
    assert not np.isnan(model_data).any()
    # simulate gains (just radnomly scattered around 1 for now)
    jones = np.ones((n_time, n_ant, n_chan, n_dir, n_cor), dtype=np.complex64)
    if sigma_f:
        jones += sigma_f * (
            np.random.randn(n_time, n_ant, n_chan, n_dir, n_cor) +
            1.0j * np.random.randn(n_time, n_ant, n_chan, n_dir, n_cor))
        assert (np.abs(jones) > 1e-5).all()
        assert not np.isnan(jones).any()
    # get vis
    time_index = np.unique(time, return_inverse=True)[1]
    jones_tmp = np.transpose(jones, [3, 0, 1, 2, 4])
    model_tmp = np.transpose(model_data, [2, 0, 1, 3])
    vis = predict_vis(time_index,
                      antenna1,
                      antenna2,
                      source_coh=model_tmp,
                      dde1_jones=jones_tmp,
                      dde2_jones=jones_tmp)
    assert not np.isnan(vis).any()
    # add noise
    if sigma_n:
        vis += sigma_n * (np.random.randn(n_row, n_chan, n_cor) +
                          1.0j * np.random.randn(n_row, n_chan, n_cor))
    weights = np.ones((n_row, n_chan, n_cor), dtype=np.float32)
    if sigma_n:
        weights /= sigma_n**2
    flag = np.zeros((n_row, n_chan, n_cor), dtype=np.bool)
    data_dict = {}
    data_dict["DATA"] = vis
    data_dict["MODEL_DATA"] = model_data
    data_dict["WEIGHT_SPECTRUM"] = weights
    data_dict["TIME"] = time
    data_dict["ANTENNA1"] = antenna1
    data_dict["ANTENNA2"] = antenna2
    data_dict["FLAG"] = flag
    data_dict['JONES'] = jones
    return data_dict
def calibrate(args, jones, alphas):
    # simple calibration to test if simulation went as expected.
    # Note do not run on large data set

    # load data
    ms = table(args.ms)
    time = ms.getcol('TIME')
    _, tbin_idx, tbin_counts = chunkify_rows(time, args.utimes_per_chunk)
    n_time = tbin_idx.size
    ant1 = ms.getcol('ANTENNA1')
    ant2 = ms.getcol('ANTENNA2')
    n_ant = np.maximum(ant1.max(), ant2.max()) + 1
    uvw = ms.getcol('UVW').astype(np.float64)
    data = ms.getcol(args.out_col)  # this is where we put the data
    # we know it is pure Stokes I so we can solve using diagonals only
    data = data[:, :, (0, 3)].astype(np.complex128)
    n_row, n_freq, n_corr = data.shape
    flag = ms.getcol('FLAG')
    flag = flag[:, :, (0, 3)]

    # get phase dir
    radec0 = table(args.ms + '::FIELD').getcol('PHASE_DIR').squeeze().astype(
        np.float64)

    # get freqs
    freq = table(args.ms + '::SPECTRAL_WINDOW').getcol('CHAN_FREQ')[0].astype(
        np.float64)
    assert freq.size == n_freq

    # now get the model
    # get source coordinates from lsm
    lsm = Tigger.load(args.sky_model)
    radec = []
    stokes = []
    spi = []
    ref_freqs = []

    for source in lsm.sources:
        radec.append([source.pos.ra, source.pos.dec])
        stokes.append([source.flux.I])
        tmp_spec = source.spectrum
        spi.append([tmp_spec.spi if tmp_spec is not None else 0.0])
        ref_freqs.append([tmp_spec.freq0 if tmp_spec is not None else 1.0])

    n_dir = len(stokes)
    radec = np.asarray(radec)
    lm = radec_to_lm(radec, radec0)

    # get model visibilities
    model = np.zeros((n_row, n_freq, n_dir, 2), dtype=np.complex)
    stokes = np.asarray(stokes)
    ref_freqs = np.asarray(ref_freqs)
    spi = np.asarray(spi)
    for d in range(n_dir):
        Stokes_I = stokes[d] * (freq / ref_freqs[d])**spi[d]
        model[:, :, d, 0:1] = im_to_vis(Stokes_I[None, :, None], uvw,
                                        lm[d:d + 1], freq)
        model[:, :, d, 1] = model[:, :, d, 0]

    # set weights to unity
    weight = np.ones_like(data, dtype=np.float64)

    # initialise gains
    jones0 = np.ones((n_time, n_ant, n_freq, n_dir, n_corr),
                     dtype=np.complex128)

    # calibrate
    ti = timeit()
    jones_hat, jhj, jhr, k = gauss_newton(tbin_idx,
                                          tbin_counts,
                                          ant1,
                                          ant2,
                                          jones0,
                                          data,
                                          flag,
                                          model,
                                          weight,
                                          tol=1e-5,
                                          maxiter=100)
    print("%i iterations took %fs" % (k, timeit() - ti))

    # verify result
    for p in range(2):
        for q in range(p):
            diff_true = np.angle(jones[:, p] * jones[:, q].conj())
            diff_hat = np.angle(jones_hat[:, p] * jones_hat[:, q].conj())
            try:
                assert_array_almost_equal(diff_true, diff_hat, decimal=2)
            except Exception as e:
                print(e)