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 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
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