Пример #1
0
def convert_blockvisibility_to_visibility(vis: BlockVisibility) -> Visibility:
    """ Convert the BlockVisibility data with no coalescence

    :param vis: BlockVisibility to be converted
    :return: Visibility with  cindex and blockvis filled in
    """

    assert isinstance(
        vis, BlockVisibility), "vis is not a BlockVisibility: %r" % vis

    cvis, cuvw, cwts, ctime, cfrequency, cchannel_bandwidth, ca1, ca2, cintegration_time, cindex \
        = convert_blocks(vis.data['vis'], vis.data['uvw'], vis.data['weight'], vis.time, vis.integration_time,
                         vis.frequency, vis.channel_bandwidth)
    cimwt = numpy.ones(cvis.shape)
    converted_vis = Visibility(uvw=cuvw,
                               time=ctime,
                               frequency=cfrequency,
                               channel_bandwidth=cchannel_bandwidth,
                               phasecentre=vis.phasecentre,
                               antenna1=ca1,
                               antenna2=ca2,
                               vis=cvis,
                               weight=cwts,
                               imaging_weight=cimwt,
                               configuration=vis.configuration,
                               integration_time=cintegration_time,
                               polarisation_frame=vis.polarisation_frame,
                               cindex=cindex,
                               blockvis=vis)

    log.debug('convert_visibility: Original %s, converted %s' %
              (vis_summary(vis), vis_summary(converted_vis)))

    return converted_vis
def shift_vis_to_image(vis: Visibility, im: Image, tangent: bool = True, inverse: bool = False) -> Visibility:
    """Shift visibility to the FFT phase centre of the image in place

    :param vis: Visibility data
    :param im: Image model used to determine phase centre
    :param tangent: Is the shift purely on the tangent plane True|False
    :param inverse: Do the inverse operation True|False
    :return: visibility with phase shift applied and phasecentre updated

    """
    assert isinstance(vis, Visibility), "vis is not a Visibility: %r" % vis
    
    nchan, npol, ny, nx = im.data.shape
    
    # Convert the FFT definition of the phase center to world coordinates (1 relative)
    # This is the only place in ARL where the relationship between the image and visibility
    # frames is defined.
    
    image_phasecentre = pixel_to_skycoord(nx // 2 + 1, ny // 2 + 1, im.wcs, origin=1)
    if vis.phasecentre.separation(image_phasecentre).rad > 1e-15:
        if inverse:
            log.debug("shift_vis_from_image: shifting phasecentre from image phase centre %s to visibility phasecentre "
                      "%s" % (image_phasecentre, vis.phasecentre))
        else:
            log.debug("shift_vis_from_image: shifting phasecentre from vis phasecentre %s to image phasecentre %s" %
                      (vis.phasecentre, image_phasecentre))
        vis = phaserotate_visibility(vis, image_phasecentre, tangent=tangent, inverse=inverse)
        vis.phasecentre = im.phasecentre
    
    assert isinstance(vis, Visibility), "after phase_rotation, vis is not a Visibility"
    
    return vis
def weight_visibility(vis: Visibility, im: Image, **kwargs) -> Visibility:
    """ Reweight the visibility data using a selected algorithm

    Imaging uses the column "imaging_weight" when imaging. This function sets that column using a
    variety of algorithms
    
    Options are:
        - Natural: by visibility weight (optimum for noise in final image)
        - Uniform: weight of sample divided by sum of weights in cell (optimum for sidelobes)
        - Super-uniform: As uniform, by sum of weights is over extended box region
        - Briggs: Compromise between natural and uniform
        - Super-briggs: As Briggs, by sum of weights is over extended box region

    :param vis:
    :param im:
    :return: visibility with imaging_weights column added and filled
    """
    assert isinstance(vis, Visibility), "vis is not a Visibility: %r" % vis

    assert get_parameter(kwargs, "padding", False) is False
    spectral_mode, vfrequencymap = get_frequency_map(vis, im)
    polarisation_mode, vpolarisationmap = get_polarisation_map(vis, im)
    uvw_mode, shape, padding, vuvwmap = get_uvw_map(vis, im)

    density = None
    densitygrid = None

    weighting = get_parameter(kwargs, "weighting", "uniform")
    vis.data['imaging_weight'], density, densitygrid = weight_gridding(
        im.data.shape, vis.data['weight'], vuvwmap, vfrequencymap,
        vpolarisationmap, weighting)

    return vis, density, densitygrid
Пример #4
0
def coalesce_visibility(vis: BlockVisibility, **kwargs) -> Visibility:
    """ Coalesce the BlockVisibility data. The output format is a Visibility, as needed for imaging

    Coalesce by baseline-dependent averaging (optional). The number of integrations averaged goes as the ratio of the
    maximum possible baseline length to that for this baseline. This number can be scaled by coalescence_factor and
    limited by max_coalescence.
    
    When faceting, the coalescence factors should be roughly the same as the number of facets on one axis.

    If coalescence_factor=0.0 then just a format conversion is done

    :param vis: BlockVisibility to be coalesced
    :return: Coalesced visibility with  cindex and blockvis filled in
    """
    # 将blockvisibility合并为一个visibility
    assert type(
        vis) is BlockVisibility, "vis is not a BlockVisibility: %r" % vis

    time_coal = get_parameter(kwargs, 'time_coal', 0.0)
    max_time_coal = get_parameter(kwargs, 'max_time_coal', 100)
    frequency_coal = get_parameter(kwargs, 'frequency_coal', 0.0)
    max_frequency_coal = get_parameter(kwargs, 'max_frequency_coal', 100)

    if time_coal == 0.0 and frequency_coal == 0.0:
        # 若time和frequency的合并率均为0,则只做一个简单的blockvisibility到visibility的变换
        return convert_blockvisibility_to_visibility((vis))
    # 否则使用average_in_blocks做一系列较为复杂的合并变换
    cvis, cuvw, cwts, ctime, cfrequency, cchannel_bandwidth, ca1, ca2, cintegration_time, cindex \
        = average_in_blocks(vis.data['vis'], vis.data['uvw'], vis.data['weight'], vis.time, vis.integration_time,
                            vis.frequency, vis.channel_bandwidth, time_coal, max_time_coal,
                            frequency_coal, max_frequency_coal)
    cimwt = numpy.ones(cvis.shape)
    coalesced_vis = Visibility(uvw=cuvw,
                               time=ctime,
                               frequency=cfrequency,
                               channel_bandwidth=cchannel_bandwidth,
                               phasecentre=vis.phasecentre,
                               antenna1=ca1,
                               antenna2=ca2,
                               vis=cvis,
                               weight=cwts,
                               imaging_weight=cimwt,
                               configuration=vis.configuration,
                               integration_time=cintegration_time,
                               polarisation_frame=vis.polarisation_frame,
                               cindex=cindex,
                               blockvis=vis)

    log.debug(
        'coalesce_visibility: Created new Visibility for coalesced data, coalescence factors (t,f) = (%.3f,%.3f)'
        % (time_coal, frequency_coal))
    log.debug('coalesce_visibility: Maximum coalescence (t,f) = (%d, %d)' %
              (max_time_coal, max_frequency_coal))
    log.debug('coalesce_visibility: Original %s, coalesced %s' %
              (vis_summary(vis), vis_summary(coalesced_vis)))

    return coalesced_vis
Пример #5
0
def visibility_gather(visibility_list: List[Visibility], vis: Visibility, vis_iter, vis_slices=1,
                      **kwargs) -> Visibility:
    """Gather a list of subvisibilities back into a visibility
    
    The iterator setup must be the same as used in the scatter.

    :param visibility_list: List of subvisibilities
    :param vis: Output visibility
    :param vis_iter: visibility iterator
    :return: vis
    """
    
    for i, rows in enumerate(vis_iter(vis, vis_slices=vis_slices, **kwargs)):
        assert i < len(visibility_list), "Gather not consistent with scatter"
        if numpy.sum(rows) and visibility_list[i] is not None:
            vis.data[rows] = visibility_list[i].data[...]
    
    return vis
Пример #6
0
def visibility_gather_channel(vis_list: List[Visibility], vis: Visibility = None, **kwargs):
    """ Gather a visibility by channel
    
    :param vis_list:
    :param vis:
    :param kwargs:
    :return:
    """
    
    cols = ['vis', 'weight']
    
    if vis is None:

        vis_shape = numpy.array(vis_list[0].vis.shape)
        vis_shape[-2] = len(vis_list)
        for v in vis_list:
            assert len(v.frequency) == 1
            assert len(v.channel_bandwidth) == 1
        vis = BlockVisibility(data=None,
                              frequency=numpy.array([v.frequency[0] for v in vis_list]),
                              channel_bandwidth=numpy.array([v.channel_bandwidth[0] for v in vis_list]),
                              phasecentre=vis_list[0].phasecentre,
                              configuration=vis_list[0].configuration,
                              uvw=vis_list[0].uvw,
                              time=vis_list[0].time,
                              vis=numpy.zeros(vis_shape, dtype=vis_list[0].vis.dtype),
                              weight=numpy.ones(vis_shape, dtype=vis_list[0].weight.dtype),
                              integration_time=vis_list[0].integration_time,
                              polarisation_frame=vis_list[0].polarisation_frame)
    
    assert len(vis.frequency) == len(vis_list)
    
    for chan, _ in enumerate(vis_list):
        subvis = vis_list[chan]
        assert abs(subvis.frequency[0] - vis.frequency[chan]) < 1e-15
        for col in cols:
            vis.data[col][..., chan, :] = subvis.data[col][..., 0, :]
        vis.frequency[chan] = subvis.frequency[0]
        
    nchan = vis.vis.shape[-2]
    assert nchan == len(vis.frequency)
    
    return vis
Пример #7
0
def visibility_para_to_visibility(viss: List[visibility_for_para],
                                  vis_share: visibility_share,
                                  mode="nto1") -> Visibility:
    '''
        拆分后的visibility还原为原visibility
    :param viss: 待还原的visbility_for_para list
    :param visibility: 共享的visibility数据
    :return:
    '''
    if mode == "nto1":
        npol = vis_share.npol
        nvis = vis_share.nvis
        desc = [('uvw', '>f8', (3, )), ('time', '>f8'), ('frequency', '>f8'),
                ('channel_bandwidth', '>f8'), ('integration_time', '>f8'),
                ('antenna1', '>i8'), ('antenna2', '>i8'),
                ('vis', '>c16', (npol, )), ('weight', '>f8', (npol, )),
                ('imaging_weight', '>f8', (npol, ))]
        data = np.zeros(shape=[nvis], dtype=desc)
        for vis in viss:
            if type(vis) == tuple:
                vis = vis[1]
            index = vis.keys["channel"] + compute_baseline_index(vis.keys['ant1'], vis.keys['ant2'], vis_share.nant) \
                                            * vis_share.nchan + vis.keys['time'] * vis_share.nchan \
                                            * (vis_share.nant * (vis_share.nant - 1)) // 2
            data['uvw'][index] = vis.uvw[0]
            data['time'][index] = vis.time[0]
            data['frequency'][index] = vis.frequency[0]
            data['channel_bandwidth'][index] = vis.channel_bandwidth[0]
            data['integration_time'][index] = vis.integration_time[0]
            data['antenna1'][index] = vis.antenna1[0]
            data['antenna2'][index] = vis.antenna2[0]
            data['vis'][index] = vis.vis[0]
            data['weight'][index] = vis.weight[0]
            data['imaging_weight'][index] = vis.imaging_weight[0]

        visibility = Visibility(
            data=data,
            phasecentre=vis_share.phasecentre,
            configuration=vis_share.configuration,
            polarisation_frame=vis_share.polarisation_frame)

    elif mode == "1to1":
        npol = vis_share.npol
        nvis = vis_share.nvis
        desc = [('uvw', '>f8', (3, )), ('time', '>f8'), ('frequency', '>f8'),
                ('channel_bandwidth', '>f8'), ('integration_time', '>f8'),
                ('antenna1', '>i8'), ('antenna2', '>i8'),
                ('vis', '>c16', (npol, )), ('weight', '>f8', (npol, )),
                ('imaging_weight', '>f8', (npol, ))]
        data = np.zeros(shape=[nvis], dtype=desc)
        for vis in viss:
            if type(vis) == tuple:
                vis = vis[1]
            for i in range(vis.nvis):
                index = vis.keys[i]["channel"] + compute_baseline_index(vis.keys[i]['ant1'], vis.keys[i]['ant2'], vis_share.nant) \
                                                * vis_share.nchan + vis.keys[i]['time'] * vis_share.nchan \
                                                * (vis_share.nant * (vis_share.nant - 1)) // 2
                data['uvw'][index] = vis.uvw[i]
                data['time'][index] = vis.time[i]
                data['frequency'][index] = vis.frequency[i]
                data['channel_bandwidth'][index] = vis.channel_bandwidth[i]
                data['integration_time'][index] = vis.integration_time[i]
                data['antenna1'][index] = vis.antenna1[i]
                data['antenna2'][index] = vis.antenna2[i]
                data['vis'][index] = vis.vis[i]
                data['weight'][index] = vis.weight[i]
                data['imaging_weight'][index] = vis.imaging_weight[i]
        visibility = Visibility(
            data=data,
            phasecentre=vis_share.phasecentre,
            configuration=vis_share.configuration,
            polarisation_frame=vis_share.polarisation_frame)

    return visibility
def create_visibility(config: Configuration,
                      times: numpy.array,
                      frequency: numpy.array,
                      channel_bandwidth,
                      phasecentre: SkyCoord,
                      weight: float,
                      polarisation_frame=PolarisationFrame('stokesI'),
                      integration_time=1.0) -> Visibility:
    """ Create a Visibility from Configuration, hour angles, and direction of source

    Note that we keep track of the integration time for BDA purposes

    :param config: Configuration of antennas
    :param times: hour angles in radians
    :param frequency: frequencies (Hz] [nchan]
    :param weight: weight of a single sample
    :param phasecentre: phasecentre of observation
    :param channel_bandwidth: channel bandwidths: (Hz] [nchan]
    :param integration_time: Integration time ('auto' or value in s)
    :param polarisation_frame: PolarisationFrame('stokesI')
    :return: Visibility
    """
    assert phasecentre is not None, "Must specify phase centre"

    if polarisation_frame is None:
        polarisation_frame = correlate_polarisation(config.receptor_frame)

    nch = len(frequency)
    ants_xyz = config.data['xyz']
    nants = len(config.data['names'])
    nbaselines = int(nants * (nants - 1) / 2)
    ntimes = len(times)
    npol = polarisation_frame.npol
    nrows = nbaselines * ntimes * nch
    nrowsperintegration = nbaselines * nch
    row = 0
    rvis = numpy.zeros([nrows, npol], dtype='complex')
    rweight = weight * numpy.ones([nrows, npol])
    rtimes = numpy.zeros([nrows])
    rfrequency = numpy.zeros([nrows])
    rchannel_bandwidth = numpy.zeros([nrows])
    rantenna1 = numpy.zeros([nrows], dtype='int')
    rantenna2 = numpy.zeros([nrows], dtype='int')
    ruvw = numpy.zeros([nrows, 3])

    # Do each hour angle in turn
    for iha, ha in enumerate(times):

        # Calculate the positions of the antennas as seen for this hour angle
        # and declination
        ant_pos = xyz_to_uvw(ants_xyz, ha, phasecentre.dec.rad)
        rtimes[row:row + nrowsperintegration] = ha * 43200.0 / numpy.pi

        # Loop over all pairs of antennas. Note that a2>a1
        for a1 in range(nants):
            for a2 in range(a1 + 1, nants):
                rantenna1[row:row + nch] = a1
                rantenna2[row:row + nch] = a2

                # Loop over all frequencies and polarisations
                for ch in range(nch):
                    # noinspection PyUnresolvedReferences
                    k = frequency[ch] / constants.c.value
                    ruvw[row, :] = (ant_pos[a2, :] - ant_pos[a1, :]) * k
                    rfrequency[row] = frequency[ch]
                    rchannel_bandwidth[row] = channel_bandwidth[ch]
                    row += 1

    assert row == nrows
    rintegration_time = numpy.full_like(rtimes, integration_time)
    vis = Visibility(uvw=ruvw,
                     time=rtimes,
                     antenna1=rantenna1,
                     antenna2=rantenna2,
                     frequency=rfrequency,
                     vis=rvis,
                     weight=rweight,
                     imaging_weight=rweight,
                     integration_time=rintegration_time,
                     channel_bandwidth=rchannel_bandwidth,
                     polarisation_frame=polarisation_frame)
    vis.phasecentre = phasecentre
    vis.configuration = config
    log.info("create_visibility: %s" % (vis_summary(vis)))
    assert isinstance(vis, Visibility), "vis is not a Visibility: %r" % vis

    return vis
def create_visibility_from_ms(msname, channum=0):
    """ Minimal MS to Visibility converter

    The MS format is much more general than the ARL Visibility so we cut many corners. This requires casacore to be
    installed. If not an exception ModuleNotFoundError is raised.

    Creates a list of Visibilities, one per phasecentre
    """
    try:
        from casacore.tables import table  # pylint: disable=import-error
    except ModuleNotFoundError:
        raise ModuleNotFoundError("casacore is not installed")

    tab = table(msname)
    print(tab.info())
    fields = numpy.unique(tab.getcol('FIELD_ID'))
    print("Found unique field ids %s" % fields)
    vis_list = list()
    for field in fields:
        # First get the main table information
        ms = tab.query("FIELD_ID==%d" % field)
        print("Found %d rows for field %d" % (ms.nrows(), field))
        time = ms.getcol('TIME')
        channels = len(numpy.transpose(ms.getcol('DATA'))[0])
        print("Found %d channels" % (channels))
        try:
            vis = ms.getcol('DATA')[:, channum, :]
        except IndexError:
            raise IndexError("channel number exceeds max. within ms")
        weight = ms.getcol('WEIGHT')
        uvw = -1 * ms.getcol('UVW')
        antenna1 = ms.getcol('ANTENNA1')
        antenna2 = ms.getcol('ANTENNA2')
        integration_time = ms.getcol('INTERVAL')
        ddid = ms.getcol('DATA_DESC_ID')

        # Now get info from the subtables
        spwtab = table('%s/SPECTRAL_WINDOW' % msname, ack=False)
        cfrequency = spwtab.getcol('CHAN_FREQ')
        frequency = numpy.array([cfrequency[dd] for dd in ddid])[:, channum]
        cchannel_bandwidth = spwtab.getcol('CHAN_WIDTH')
        channel_bandwidth = numpy.array(
            [cchannel_bandwidth[dd] for dd in ddid])[:, 0]

        uvw *= frequency[:, numpy.newaxis] / constants.c.to('m/s').value

        # Get polarisation info
        # poltab = table('%s/POLARIZATION' % msname, ack=False)
        # corr_type = poltab.getcol('CORR_TYPE')
        # TODO: Do interpretation correctly
        polarisation_frame = PolarisationFrame('stokesIQUV')

        # Get configuration
        anttab = table('%s/ANTENNA' % msname, ack=False)
        mount = anttab.getcol('MOUNT')
        names = anttab.getcol('NAME')
        diameter = anttab.getcol('DISH_DIAMETER')
        xyz = anttab.getcol('POSITION')
        configuration = Configuration(name='',
                                      data=None,
                                      location=None,
                                      names=names,
                                      xyz=xyz,
                                      mount=mount,
                                      frame=None,
                                      receptor_frame=ReceptorFrame("linear"),
                                      diameter=diameter)

        # Get phasecentres
        fieldtab = table('%s/FIELD' % msname, ack=False)
        pc = fieldtab.getcol('PHASE_DIR')[field, 0, :]
        phasecentre = SkyCoord(ra=[pc[0]] * u.rad,
                               dec=pc[1] * u.rad,
                               frame='icrs',
                               equinox='J2000')

        vis_list.append(
            Visibility(uvw=uvw,
                       time=time,
                       antenna1=antenna1,
                       antenna2=antenna2,
                       frequency=frequency,
                       vis=vis,
                       weight=weight,
                       imaging_weight=weight,
                       integration_time=integration_time,
                       channel_bandwidth=channel_bandwidth,
                       configuration=configuration,
                       phasecentre=phasecentre,
                       polarisation_frame=polarisation_frame))
    return vis_list