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
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_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
def divide_kernel(ixs): vis, model_vis = ixs return divide_visibility(vis, model_vis)