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
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 total_rows = 0 for chunk, rows in enumerate(vis_timeslice_iter(self.vis)): 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)
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
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
def apply_gaintable(vis: BlockVisibility, gt: GainTable, inverse=False, **kwargs) -> BlockVisibility: """Apply a gain table to a block visibility The corrected visibility is:: V_corrected = {g_i * g_j^*}^-1 V_obs If the visibility data are polarised e.g. polarisation_frame("linear") then the inverse operator represents an actual inverse of the gains. :param vis: Visibility to have gains applied :param gt: Gaintable to be applied :param inverse: Apply the inverse (default=False) :return: input vis with gains applied """ assert type( vis) is BlockVisibility, "vis is not a BlockVisibility: %r" % vis assert type(gt) is GainTable, "gt is not a GainTable: %r" % gt assert_vis_gt_compatible(vis, gt) if inverse: log.debug('apply_gaintable: Apply inverse gaintable') else: log.debug('apply_gaintable: Apply gaintable') # 按照time对vis进行切片 for chunk, rows in enumerate(vis_timeslice_iter(vis)): vistime = numpy.average(vis.time[rows]) integration_time = numpy.average(vis.integration_time[rows]) gaintable_rows = abs(gt.time - vistime) < integration_time / 2.0 # Lookup the gain for this set of visibilities gain = gt.data['gain'][gaintable_rows] # The shape of the mueller matrix is ntimes, nant, nchan, nrec, _ = gain.shape original = vis.vis[rows] applied = copy.deepcopy(original) for time in range(ntimes): for a1 in range(vis.nants - 1): for a2 in range(a1 + 1, vis.nants): for chan in range(nchan): mueller = numpy.kron( gain[time, a1, chan, :, :], numpy.conjugate(gain[time, a2, chan, :, :])) if inverse: mueller = numpy.linalg.inv(mueller) applied[time, a2, a1, chan, :] = numpy.matmul( mueller, original[time, a2, a1, chan, :]) vis.data['vis'][rows] = applied return vis
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
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)
def apply_gaintable(vis: BlockVisibility, gt: GainTable, inverse=False, **kwargs) -> BlockVisibility: """Apply a gain table to a block visibility The corrected visibility is:: V_corrected = {g_i * g_j^*}^-1 V_obs If the visibility data are polarised e.g. polarisation_frame("linear") then the inverse operator represents an actual inverse of the gains. :param vis: Visibility to have gains applied :param gt: Gaintable to be applied :param inverse: Apply the inverse (default=False) :return: input vis with gains applied """ assert isinstance( vis, BlockVisibility), "vis is not a BlockVisibility: %r" % vis assert isinstance(gt, GainTable), "gt is not a GainTable: %r" % gt assert_vis_gt_compatible(vis, gt) if inverse: log.debug('apply_gaintable: Apply inverse gaintable') else: log.debug('apply_gaintable: Apply gaintable') is_scalar = gt.gain.shape[-2:] == (1, 1) if is_scalar: log.debug('apply_gaintable: scalar gains') for chunk, rows in enumerate(vis_timeslice_iter(vis, **kwargs)): if numpy.sum(rows) > 0: vistime = numpy.average(vis.time[rows]) gaintable_rows = abs(gt.time - vistime) < gt.interval / 2.0 # Lookup the gain for this set of visibilities gain = gt.data['gain'][gaintable_rows] # The shape of the mueller matrix is ntimes, nant, nchan, nrec, _ = gain.shape original = vis.vis[rows] applied = copy.deepcopy(original) for time in range(ntimes): for a1 in range(vis.nants - 1): for a2 in range(a1 + 1, vis.nants): if is_scalar: smueller = gain[time, a1, :, 0] * numpy.conjugate( gain[time, a2, :, 0]) if inverse: if numpy.abs(smueller).all() > 0.0: applied[time, a2, a1, :, 0][..., numpy.newaxis] = original[ time, a2, a1, :, 0][..., numpy.newaxis] / smueller else: applied[time, a2, a1, :, 0][..., numpy.newaxis] = original[ time, a2, a1, :, 0][..., numpy.newaxis] * smueller else: for chan in range(nchan): mueller = numpy.kron( gain[time, a1, chan, :, :], numpy.conjugate(gain[time, a2, chan, :, :])) if inverse: # If the Mueller is singular, ignore it try: mueller = numpy.linalg.inv(mueller) applied[time, a2, a1, chan, :] = numpy.matmul( mueller, original[time, a2, a1, chan, :]) except numpy.linalg.linalg.LinAlgError: applied[time, a2, a1, chan, :] = original[time, a2, a1, chan, :] else: applied[time, a2, a1, chan, :] = numpy.matmul( mueller, original[time, a2, a1, chan, :]) vis.data['vis'][rows] = applied return vis
def test_vis_timeslice_iterator_single(self): self.actualSetUp(times=numpy.zeros([1])) nchunks = len(list(vis_timeslice_iter(self.vis))) log.debug('Found %d chunks' % (nchunks)) for chunk, rows in enumerate(vis_timeslice_iter(self.vis)): assert len(rows)
def solve_gaintable(vis: BlockVisibility, modelvis: BlockVisibility, phase_only=True, niter=30, tol=1e-8, crosspol=False, **kwargs) -> GainTable: """Solve a gain table to a block visibility :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 :returns: GainTable containing solution """ assert type( vis) is BlockVisibility, "vis is not a BlockVisibility: %r" % vis assert type( modelvis ) is BlockVisibility, "modelvis is not a BlockVisibility: %r" % vis if phase_only: log.info('solve_gaintable: Solving for phase only') else: log.info('solve_gaintable: Solving for complex gain') gt = create_gaintable_from_blockvisibility(vis) for chunk, rows in enumerate(vis_timeslice_iter(vis)): x, xwt = remove_model(vis.vis[rows], vis.weight[rows], modelvis.vis[rows], isscalar=vis.polarisation_frame.npol == 1, crosspol=crosspol) # Now average over time, chan. The axes of x are time, antenna2, antenna1, chan, pol xave = numpy.average(x, axis=0) xwtAve = numpy.average(xwt, axis=0) mask = xwtAve <= 0.0 xave[mask] = 0.0 gainshape = gt.data['gain'][chunk, ...].shape if vis.polarisation_frame.npol > 1: if crosspol: gt.data['gain'][chunk, ...], gt.data['weight'][chunk, ...], gt.data['residual'][chunk, ...] = \ solve_antenna_gains_itsubs_matrix(gainshape, xave, xwtAve, phase_only=phase_only, niter=niter, tol=tol) else: gt.data['gain'][chunk, ...], gt.data['weight'][chunk, ...], gt.data['residual'][chunk, ...] = \ solve_antenna_gains_itsubs_vector(gainshape, xave, xwtAve, phase_only=phase_only, niter=niter, tol=tol) else: gt.data['gain'][chunk, ...], gt.data['weight'][chunk, ...], gt.data['residual'][chunk, ...] = \ solve_antenna_gains_itsubs_scalar(gainshape, xave, xwtAve, phase_only=phase_only, niter=niter, tol=tol) assert type(gt) is GainTable, "gt is not a GainTable: %r" % gt return gt
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 isinstance(vis, BlockVisibility), vis assert isinstance(modelvis, BlockVisibility) or type(modelvis) is not None, vis if phase_only: log.info('solve_gaintable: Solving for phase only') else: log.info('solve_gaintable: Solving for complex gain') gt = create_gaintable_from_blockvisibility(vis) for chunk, rows in enumerate(vis_timeslice_iter(vis, **kwargs)): subvis = create_visibility_from_rows(vis, rows) if modelvis is not None: model_subvis = create_visibility_from_rows(modelvis, 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, chunk, 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