def solve_gaintable(vis: BlockVisibility, modelvis: BlockVisibility = None, gt=None, phase_only=True, niter=30,
                    tol=1e-8,
                    crosspol=False, **kwargs) -> GainTable:
    """Solve a gain table by fitting an observed visibility to a model visibility
    
    If modelvis is None, a point source model is assumed.

    :param vis: BlockVisibility containing the observed data
    :param modelvis: BlockVisibility containing the visibility predicted by a model
    :param gt: Existing gaintable
    :param phase_only: Solve only for the phases (default=True)
    :param niter: Number of iterations (default 30)
    :param tol: Iteration stops when the fractional change in the gain solution is below this tolerance
    :param crosspol: Do solutions including cross polarisations i.e. XY, YX or RL, LR
    :return: GainTable containing solution

    """
    assert isinstance(vis, BlockVisibility), vis
    if modelvis is not None:
        assert isinstance(modelvis, BlockVisibility), modelvis
    
    if phase_only:
        log.debug('solve_gaintable: Solving for phase only')
    else:
        log.debug('solve_gaintable: Solving for complex gain')
    
    if gt is None:
        log.debug("solve_gaintable: creating new gaintable")
        gt = create_gaintable_from_blockvisibility(vis, **kwargs)
    else:
        log.debug("solve_gaintable: starting from existing gaintable")

    for row in range(gt.ntimes):
        vis_rows = numpy.abs(vis.time - gt.time[row]) < gt.interval[row] / 2.0
        if numpy.sum(vis_rows) > 0:
            subvis = create_visibility_from_rows(vis, vis_rows)
            if modelvis is not None:
                model_subvis = create_visibility_from_rows(modelvis, vis_rows)
                pointvis = divide_visibility(subvis, model_subvis)
                x = numpy.sum(pointvis.vis * pointvis.weight, axis=0)
                xwt = numpy.sum(pointvis.weight, axis=0)
            else:
                x = numpy.sum(subvis.vis * subvis.weight, axis=0)
                xwt = numpy.sum(subvis.weight, axis=0)
            
            mask = numpy.abs(xwt) > 0.0
            x_shape = x.shape
            x[mask] = x[mask] / xwt[mask]
            x[~mask] = 0.0
            x = x.reshape(x_shape)
            
            gt = solve_from_X(gt, x, xwt, row, crosspol, niter, phase_only,
                              tol, npol=vis.polarisation_frame.npol)
    
    assert isinstance(gt, GainTable), "gt is not a GainTable: %r" % gt
    
    assert_vis_gt_compatible(vis, gt)
    
    return gt
Exemple #2
0
def solve_gaintable(vis: BlockVisibility, modelvis: BlockVisibility=None, phase_only=True, niter=30, tol=1e-8,
                    crosspol=False, **kwargs) -> GainTable:
    """Solve a gain table by fitting an observed visibility to a model visibility
    
    If modelvis is None, a point source model is assumed.

    :param vis: BlockVisibility containing the observed data
    :param modelvis: BlockVisibility containing the visibility predicted by a model
    :param phase_only: Solve only for the phases (default=True)
    :param niter: Number of iterations (default 30)
    :param tol: Iteration stops when the fractional change in the gain solution is below this tolerance
    :param crosspol: Do solutions including cross polarisations i.e. XY, YX or RL, LR
    :return: GainTable containing solution

    """
    assert type(vis) is BlockVisibility, "vis is not a BlockVisibility: %r" % vis
    assert type(modelvis) is BlockVisibility or type(modelvis) is None, "modelvis is not None or a " \
                                                                            "BlockVisibility: %r" % vis
    
    if phase_only:
        log.info('solve_gaintable: Solving for phase only')
    else:
        log.info('solve_gaintable: Solving for complex gain')

    # 根据blockvisibility的元数据初始化一个gaintable
    gt = create_gaintable_from_blockvisibility(vis)
    for chunk, rows in enumerate(vis_timeslice_iter(vis, **kwargs)): # 对visibility按照time切片
        # 切片好的visibility shape: [1,nant,nant,nchan,npol]
        subvis = create_visibility_from_rows(vis, rows)
        #若存在model
        if modelvis is not None:
            # model_visibility也要以相同的方式按time切片
            model_subvis = create_visibility_from_rows(modelvis, rows)
            # 两个vis相除计算得到新的block_vis,其中的元数据未改变,只有vis和weight发生了改变
            pointvis = divide_visibility(subvis, model_subvis)
            # 此处因为第0个axis是time轴,并且vis已经按照time分片,所以按照第0axis做了average以后值不发生变化
            x = numpy.average(pointvis.vis, axis=0)
            xwt = numpy.average(pointvis.weight, axis=0)

        else:
            x = numpy.average(subvis.vis, axis=0)
            xwt = numpy.average(subvis.weight, axis=0)

        # 将数据填入gaintable中
        # solve 和 timeslot的分界线
        gt = solve_from_X(gt, x, xwt, chunk, crosspol, niter, phase_only,
                        tol, npol=vis.polarisation_frame.npol)


    assert type(gt) is GainTable, "gt is not a GainTable: %r" % gt
    
    assert_vis_gt_compatible(vis, gt)

    
    return gt
Exemple #3
0
 def test_solve_gaintable_scalar_pointsource(self):
     self.actualSetup('stokesI', 'stokesI', f=[100.0])
     gt = create_gaintable_from_blockvisibility(self.vis)
     log.info("Created gain table: %s" % (gaintable_summary(gt)))
     gt = simulate_gaintable(gt, phase_error=10.0, amplitude_error=0.0)
     original = copy_visibility(self.vis)
     self.vis = apply_gaintable(self.vis, gt)
     point_vis = divide_visibility(self.vis, original)
     gtsol = solve_gaintable(point_vis, phase_only=True, niter=200)
     residual = numpy.max(gtsol.residual)
     assert residual < 3e-8, "Max residual = %s" % (residual)
     assert numpy.max(numpy.abs(gtsol.gain - 1.0)) > 0.1
Exemple #4
0
def divide_kernel(ixs):
    vis, model_vis = ixs
    return divide_visibility(vis, model_vis)