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_create_visibility_from_rows_makecopy(self):
     self.vis = create_visibility(self.lowcore, self.times, self.frequency, phasecentre=self.phasecentre,
                                       weight=1.0, channel_bandwidth=self.channel_bandwidth)
     rows = self.vis.time > 150.0
     for makecopy in [True, False]:
         selected_vis = create_visibility_from_rows(self.vis, rows, makecopy=makecopy)
         assert selected_vis.nvis == numpy.sum(numpy.array(rows))
Exemple #4
0
 def test_vis_timeslice_iterator_timeslice(self):
     self.actualSetUp()
     for chunk, rows in enumerate(
             vis_timeslice_iter(self.vis, timeslice=65.0)):
         visslice = create_visibility_from_rows(self.vis, rows)
         assert visslice.vis[0].real == visslice.time[0]
         assert len(rows)
         assert numpy.sum(rows) < self.vis.nvis
Exemple #5
0
 def test_coalesce_decoalesce_with_iter(self):
     for rows in vis_timeslice_iter(self.blockvis):
         visslice = create_visibility_from_rows(self.blockvis, rows)
         cvisslice = convert_blockvisibility_to_visibility(visslice)
         assert numpy.min(cvisslice.frequency) == numpy.min(self.frequency)
         assert numpy.min(cvisslice.frequency) > 0.0
         dvisslice = decoalesce_visibility(cvisslice)
         assert dvisslice.nvis == visslice.nvis
Exemple #6
0
 def test_vis_wstack_iterator(self):
     self.actualSetUp()
     nchunks = len(list(vis_wstack_iter(self.vis, wstack=10.0)))
     log.debug('Found %d chunks' % (nchunks))
     assert nchunks > 1
     for chunk, rows in enumerate(vis_wstack_iter(self.vis, wstack=10.0)):
         assert len(rows)
         visslice = create_visibility_from_rows(self.vis, rows)
         assert numpy.sum(visslice.nvis) < self.vis.nvis
Exemple #7
0
 def test_vis_timeslice_iterator(self):
     self.actualSetUp()
     nchunks = len(list(vis_timeslice_iter(self.vis)))
     log.debug('Found %d chunks' % (nchunks))
     assert nchunks > 1
     for chunk, rows in enumerate(vis_timeslice_iter(self.vis)):
         visslice = create_visibility_from_rows(self.vis, rows)
         assert visslice.vis[0].real == visslice.time[0]
         assert len(rows)
         assert numpy.sum(rows) < self.vis.nvis
Exemple #8
0
 def test_vis_slice_iterator_vis_slices(self):
     self.actualSetUp()
     total_rows = 0
     for chunk, rows in enumerate(vis_slice_iter(self.vis, vis_slices=11)):
         visslice = create_visibility_from_rows(self.vis, rows)
         total_rows += visslice.nvis
         assert len(rows)
         assert visslice.vis[0].real == visslice.time[0]
     assert total_rows == self.vis.nvis, "Total rows iterated %d, Original rows %d" % (
         total_rows, self.vis.nvis)
 def scatter_vis(vis):
     # Scatter along the visibility iteration axis
     if isinstance(vis, BlockVisibility):
         avis = coalesce_visibility(vis, **kwargs)
     else:
         avis = vis
     result = [
         create_visibility_from_rows(avis, rows)
         for rows in vis_iter(avis, vis_slices=vis_slices, **kwargs)
     ]
     return result
 def scatter_vis(vis):
     if isinstance(vis, BlockVisibility):
         avis = coalesce_visibility(vis, **kwargs)
     else:
         avis = vis
     result = [
         create_visibility_from_rows(avis, rows)
         for rows in vis_iter(avis, vis_slices=vis_slices, **kwargs)
     ]
     assert len(result) == vis_slices, "result %s, vis_slices %d" % (
         str(result), vis_slices)
     return result
Exemple #11
0
 def test_vis_timeslice_iterator_timeslice(self):
     self.actualSetUp()
     total_rows = 0
     for chunk, rows in enumerate(
             vis_timeslice_iter(self.vis, timeslice=65.0)):
         visslice = create_visibility_from_rows(self.vis, rows)
         if visslice is not None:
             total_rows += visslice.nvis
             assert visslice.vis[0].real == visslice.time[0]
             assert len(rows)
             assert numpy.sum(rows) < self.vis.nvis
     assert total_rows == self.vis.nvis, "Total rows iterated %d, Original rows %d" % (
         total_rows, self.vis.nvis)
Exemple #12
0
 def test_vis_wstack_iterator(self):
     self.actualSetUp()
     nchunks = len(list(vis_wstack_iter(self.vis, wstack=10.0)))
     log.debug('Found %d chunks' % (nchunks))
     assert nchunks > 1
     total_rows = 0
     for chunk, rows in enumerate(vis_wstack_iter(self.vis, wstack=10.0)):
         assert len(rows)
         visslice = create_visibility_from_rows(self.vis, rows)
         total_rows += visslice.nvis
         assert numpy.sum(visslice.nvis) < self.vis.nvis
     assert total_rows == self.vis.nvis, "Total rows iterated %d, Original rows %d" % (
         total_rows, self.vis.nvis)
Exemple #13
0
def uv_cut(vis, uv_max):
    """Cut the visibility data at uv-distances beyond uvmax.
        
    Args:
    vis (obj): ARL visibility data.
    uv_max (float): maximum uv-coordinate.
    
    Returns:
    vis: New visibility data.
    """
    # Cut off data beyond the maximum uv-distance:
    uv_dist = np.sqrt(vis.data['uvw'][:, 0]**2 + vis.data['uvw'][:, 1]**2)
    vis = create_visibility_from_rows(vis, uv_dist < uv_max)
    return vis
Exemple #14
0
def visibility_scatter(vis: Visibility, vis_iter, vis_slices=1, **kwargs) -> List[Visibility]:
    """Scatter a visibility into a list of subvisibilities

    :param vis: Visibility
    :param vis_iter: visibility iterator
    :return: list of subvisibilitys
    """
    
    visibility_list = list()
    for i, rows in enumerate(vis_iter(vis, vis_slices=vis_slices, **kwargs)):
        subvis = create_visibility_from_rows(vis, rows)
        visibility_list.append(subvis)
        
    return visibility_list
Exemple #15
0
 def test_vis_timeslice_iterator(self):
     self.actualSetUp()
     nchunks = len(list(vis_timeslice_iter(self.vis, timeslice='auto')))
     log.debug('Found %d chunks' % (nchunks))
     assert nchunks > 1
     total_rows = 0
     for chunk, rows in enumerate(
             vis_timeslice_iter(self.vis, timeslice='auto')):
         visslice = create_visibility_from_rows(self.vis, rows)
         total_rows += visslice.nvis
         assert visslice.vis[0].real == visslice.time[0]
         assert len(rows)
         assert numpy.sum(rows) < self.vis.nvis
     assert total_rows == self.vis.nvis, "Total rows iterated %d, Original rows %d" % (
         total_rows, self.vis.nvis)
Exemple #16
0
def predict_with_vis_iterator(vis: Visibility, model: Image, vis_iter=vis_slice_iter,
                              predict=predict_2d, **kwargs) -> Visibility:
    """Iterate through prediction in chunks
    
    This knows about the structure of predict in different execution frameworks but not
    anything about the actual processing.
    
    """
    log.debug("predict_with_vis_iterator: Processing chunks")
    if not isinstance(vis, Visibility):
        svis = coalesce_visibility(vis, **kwargs)
    else:
        svis = vis
        
    # Do each chunk in turn
    for rows in vis_iter(svis, **kwargs):
        if numpy.sum(rows) and svis is not None:
            visslice = create_visibility_from_rows(svis, rows)
            visslice.data['vis'][...] = 0.0
            visslice = predict(visslice, model, **kwargs)
            svis.data['vis'][rows] += visslice.data['vis']
    return svis
Exemple #17
0
def invert_with_vis_iterator(vis: Visibility, im: Image, dopsf=False, normalize=True, vis_iter=vis_slice_iter,
                             invert=invert_2d, **kwargs):
    """ Invert using a specified iterator and invert

    This knows about the structure of invert in different execution frameworks but not
    anything about the actual processing.

    :param vis:
    :param im:
    :param dopsf: Make the psf instead of the dirty image
    :param normalize: Normalize by the sum of weights (True)
    :param kwargs:
    :return:
    """
    resultimage = create_empty_image_like(im)

    if type(vis) is not Visibility:
        svis = coalesce_visibility(vis, **kwargs)
    else:
        svis = vis


    i = 0
    for rows in vis_iter(svis, **kwargs):
        if numpy.sum(rows) and svis is not None:
            visslice = create_visibility_from_rows(svis, rows)
            workimage, sumwt = invert(visslice, im, dopsf, normalize=False, **kwargs)
            resultimage.data += workimage.data
            if i == 0:
                totalwt = sumwt
            else:
                totalwt += sumwt
            i += 1

    if normalize:
        resultimage = normalize_sumwt(resultimage, totalwt)

    return resultimage, totalwt
 def scatter_vis(vis):
     if isinstance(vis, BlockVisibility):
         avis = coalesce_visibility(vis, **kwargs)
     else:
         avis = vis
     return [create_visibility_from_rows(vis, rows) for rows in vis_iter(avis, vis_slices=vis_slices, **kwargs)]
def invert_function(vis,
                    im: Image,
                    dopsf=False,
                    normalize=True,
                    context='2d',
                    inner=None,
                    **kwargs):
    """ Invert using algorithm specified by context:

     * 2d: Two-dimensional transform
     * wstack: wstacking with either vis_slices or wstack (spacing between w planes) set
     * wprojection: w projection with wstep (spacing between w places) set, also kernel='wprojection'
     * timeslice: snapshot imaging with either vis_slices or timeslice set. timeslice='auto' does every time
     * facets: Faceted imaging with facets facets on each axis
     * facets_wprojection: facets AND wprojection
     * facets_wstack: facets AND wstacking
     * wprojection_wstack: wprojection and wstacking


    :param vis:
    :param im:
    :param dopsf: Make the psf instead of the dirty image (False)
    :param normalize: Normalize by the sum of weights (True)
    :param context: Imaging context e.g. '2d', 'timeslice', etc.
    :param inner: Inner loop 'vis'|'image'
    :param kwargs:
    :return: Image, sum of weights
    """
    c = imaging_context(context)
    vis_iter = c['vis_iterator']
    image_iter = c['image_iterator']
    invert = c['invert']
    if inner is None:
        inner = c['inner']

    if not isinstance(vis, Visibility):
        svis = coalesce_visibility(vis, **kwargs)
    else:
        svis = vis

    resultimage = create_empty_image_like(im)

    if inner == 'image':
        totalwt = None
        for rows in vis_iter(svis, **kwargs):
            if numpy.sum(rows):
                visslice = create_visibility_from_rows(svis, rows)
                sumwt = 0.0
                workimage = create_empty_image_like(im)
                for dpatch in image_iter(workimage, **kwargs):
                    result, sumwt = invert(visslice,
                                           dpatch,
                                           dopsf,
                                           normalize=False,
                                           **kwargs)
                    # Ensure that we fill in the elements of dpatch instead of creating a new numpy arrray
                    dpatch.data[...] = result.data[...]
                # Assume that sumwt is the same for all patches
                if totalwt is None:
                    totalwt = sumwt
                else:
                    totalwt += sumwt
                resultimage.data += workimage.data
    else:
        # We assume that the weight is the same for all image iterations
        totalwt = None
        workimage = create_empty_image_like(im)
        for dpatch in image_iter(workimage, **kwargs):
            totalwt = None
            for rows in vis_iter(svis, **kwargs):
                if numpy.sum(rows):
                    visslice = create_visibility_from_rows(svis, rows)
                    result, sumwt = invert(visslice,
                                           dpatch,
                                           dopsf,
                                           normalize=False,
                                           **kwargs)
                    # Ensure that we fill in the elements of dpatch instead of creating a new numpy arrray
                    dpatch.data[...] += result.data[...]
                    if totalwt is None:
                        totalwt = sumwt
                    else:
                        totalwt += sumwt
            resultimage.data += workimage.data
            workimage.data[...] = 0.0

    assert totalwt is not None, "No valid data found for imaging"
    if normalize:
        resultimage = normalize_sumwt(resultimage, totalwt)

    return resultimage, totalwt
def predict_function(vis,
                     model: Image,
                     context='2d',
                     inner=None,
                     **kwargs) -> Visibility:
    """Predict visibilities using algorithm specified by context
    
     * 2d: Two-dimensional transform
     * wstack: wstacking with either vis_slices or wstack (spacing between w planes) set
     * wprojection: w projection with wstep (spacing between w places) set, also kernel='wprojection'
     * timeslice: snapshot imaging with either vis_slices or timeslice set. timeslice='auto' does every time
     * facets: Faceted imaging with facets facets on each axis
     * facets_wprojection: facets AND wprojection
     * facets_wstack: facets AND wstacking
     * wprojection_wstack: wprojection and wstacking

    
    :param vis:
    :param model: Model image, used to determine image characteristics
    :param context: Imaing context e.g. '2d', 'timeslice', etc.
    :param inner: Inner loop 'vis'|'image'
    :param kwargs:
    :return:


    """
    c = imaging_context(context)
    vis_iter = c['vis_iterator']
    image_iter = c['image_iterator']
    predict = c['predict']
    if inner is None:
        inner = c['inner']

    if not isinstance(vis, Visibility):
        svis = coalesce_visibility(vis, **kwargs)
    else:
        svis = vis

    result = copy_visibility(vis, zero=True)

    if inner == 'image':
        for rows in vis_iter(svis, **kwargs):
            if numpy.sum(rows):
                visslice = create_visibility_from_rows(svis, rows)
                visslice.data['vis'][...] = 0.0
                # Iterate over images
                for dpatch in image_iter(model, **kwargs):
                    result.data['vis'][...] = 0.0
                    result = predict(visslice, dpatch, **kwargs)
                    svis.data['vis'][rows] += result.data['vis']
    else:
        # Iterate over images
        for dpatch in image_iter(model, **kwargs):
            for rows in vis_iter(svis, **kwargs):
                if numpy.sum(rows):
                    visslice = create_visibility_from_rows(svis, rows)
                    result.data['vis'][...] = 0.0
                    result = predict(visslice, dpatch, **kwargs)
                    svis.data['vis'][rows] += result.data['vis']

    return svis
Exemple #21
0
 def test_vis_slice_iterator_vis_slices(self):
     self.actualSetUp()
     for chunk, rows in enumerate(vis_slice_iter(self.vis, vis_slices=11)):
         visslice = create_visibility_from_rows(self.vis, rows)
         assert len(rows)
         assert visslice.vis[0].real == visslice.time[0]