def make_e(vis, calskymodel, evis_all): # Return the estep for a given skymodel evis = copy_visibility(vis) tvis = copy_visibility(vis, zero=True) tvis = predict_skymodel_visibility(tvis, calskymodel[0]) tvis = apply_gaintable(tvis, calskymodel[1]) # E step is the data model for a window plus the difference between the observed data_models # and the summed data models or, put another way, its the observed data minus the # summed visibility for all other windows evis.data['vis'][...] = tvis.data['vis'][...] + vis.data['vis'][...] - evis_all.data['vis'][...] return evis
def degrid_visibility_from_griddata(vis, griddata, cf, **kwargs): """Degrid Visibility from a GridData :param vis: Visibility to be degridded :param griddata: GridData containing image :param cf: Convolution function (as GridData) :param kwargs: :return: Visibility """ nchan, npol, nz, oversampling, _, support, _ = cf.shape pu_grid, pu_offset, pv_grid, pv_offset, pwg_grid, pwg_fraction, pwc_grid, pwc_fraction, pfreq_grid = \ convolution_mapping(vis, griddata, cf) _, _, _, _, _, gv, gu = cf.shape newvis = copy_visibility(vis, zero=True) # coords = zip(pfreq_grid, pu_grid, pu_offset, pv_grid, pv_offset, pw_grid) du = gu // 2 dv = gv // 2 nvis = vis.vis.shape[0] for ivis in range(nvis): chan, uu, uuf, vv, vvf, zzg, zzc = pfreq_grid[ivis], pu_grid[ivis], pu_offset[ivis], pv_grid[ivis], \ pv_offset[ivis], pwg_grid[ivis], pwc_grid[ivis] # Use einsum to replace the following: # newvis.vis[i,:] = numpy.sum(griddata.data[chan, :, zzg, (vv - dv):(vv + dv), (uu - du):(uu + du)] * # cf.data[chan, :, zzc, vvf, uuf, :, :], axis=(1, 2)) newvis.vis[ivis, :] += numpy.einsum('ijk,ijk->i', griddata.data[chan, :, zzg, (vv - dv):(vv + dv), (uu - du):(uu + du)], cf.data[chan, :, zzc, vvf, uuf, :, :]) return newvis
def _predict_base(self, context='2d', extra='', fluxthreshold=1.0, facets=1, vis_slices=1, **kwargs): vis = copy_visibility(self.vis) vis.data['vis'][...] = 0 vis = predict_serial(vis, self.model, context=context, vis_slices=vis_slices, facets=facets, **kwargs) vis.data['vis'][...] -= self.vis.data['vis'][...] dirty = invert_serial(vis, self.model, context='2d', dopsf=False, normalize=True) assert numpy.max(numpy.abs(dirty[0].data)), "Residual image is empty" export_image_to_fits( dirty[0], '%s/test_imaging_predict_%s%s_dirty.fits' % (self.dir, context, extra)) maxabs = numpy.max(numpy.abs(dirty[0].data)) assert maxabs < fluxthreshold, "Error %.3f greater than fluxthreshold %.3f " % ( maxabs, fluxthreshold)
def calskymodel_fit_gaintable(evis, calskymodel, gain=0.1, niter=3, tol=1e-3, **kwargs): """Fit a gaintable to a visibility This is the update to the gain part of the window :param evis: Expected vis for this ssm :param calskymodel: csm element being fit :param gain: Gain in step :param niter: Number of iterations :param kwargs: Gaintable """ previous_gt = copy_gaintable(calskymodel[1]) gt = copy_gaintable(calskymodel[1]) model_vis = copy_visibility(evis, zero=True) model_vis = predict_skymodel_visibility(model_vis, calskymodel[0]) gt = solve_gaintable(evis, model_vis, gt=gt, niter=niter, phase_only=True, gain=0.5, tol=1e-4, **kwargs) gt.data['gain'][...] = gain * gt.data['gain'][...] + ( 1 - gain) * previous_gt.data['gain'][...] gt.data['gain'][...] /= numpy.abs(previous_gt.data['gain'][...]) return gt
def modelpartition_list_expectation_step(vis: BlockVisibility, evis_all: BlockVisibility, modelpartition, **kwargs): """Calculates E step in equation A12 This is the data model for this window plus the difference between observed data and summed data models :param evis_all: Sum data models :param csm: csm element being fit :param kwargs: :return: Data model (i.e. visibility) for this csm """ evis = copy_visibility(evis_all) tvis = copy_visibility(vis, zero=True) tvis = predict_skymodel_visibility(tvis, modelpartition[0], **kwargs) tvis = apply_gaintable(tvis, modelpartition[1]) evis.data['vis'][...] = tvis.data['vis'][...] + vis.data['vis'][...] - evis_all.data['vis'][...] return evis
def calskymodel_expectation_all(vis: BlockVisibility, calskymodels, **kwargs): """Calculates E step in equation A12 This is the sum of the data models over all skymodel :param vis: Visibility :param csm: List of (skymodel, gaintable) tuples :param kwargs: :return: Sum of data models (i.e. a visibility) """ evis = copy_visibility(vis, zero=True) tvis = copy_visibility(vis, zero=True) for csm in calskymodels: tvis.data['vis'][...] = 0.0 tvis = predict_skymodel_visibility(tvis, csm[0], **kwargs) tvis = apply_gaintable(tvis, csm[1]) evis.data['vis'][...] += tvis.data['vis'][...] return evis
def solve_modelpartition(vis, skymodels, niter=10, tol=1e-8, gain=0.25, **kwargs): """ Solve for model partitions Solve by iterating, performing E step and M step. :param vis: Initial visibility :param components: Initial components to be used :param gaintables: Initial gain tables to be used :param kwargs: :return: The individual data models and the residual visibility """ model_partition = create_modelpartition(vis, skymodels=skymodels, **kwargs) for iter in range(niter): new_modelpartitions = list() evis_all = modelpartition_expectation_all(vis, model_partition) log.debug("solve_modelpartition: Iteration %d" % (iter)) for window_index, csm in enumerate(model_partition): evis = modelpartition_expectation_step(vis, evis_all, csm, gain=gain, **kwargs) new_csm = modelpartition_maximisation_step(evis, csm, **kwargs) new_modelpartitions.append((new_csm[0], new_csm[1])) flux = new_csm[0].components[0].flux[0, 0] qa = qa_gaintable(new_csm[1]) residual = qa.data['residual'] rms_phase = qa.data['rms-phase'] log.debug( "solve_modelpartition:\t Window %d, flux %s, residual %.3f, rms phase %.3f" % (window_index, str(flux), residual, rms_phase)) model_partition = [(copy_skymodel(csm[0]), copy_gaintable(csm[1])) for csm in new_modelpartitions] residual_vis = copy_visibility(vis) final_vis = modelpartition_expectation_all(vis, model_partition) residual_vis.data['vis'][ ...] = vis.data['vis'][...] - final_vis.data['vis'][...] return model_partition, residual_vis
def rcal(vis: BlockVisibility, components, **kwargs) -> GainTable: """ Real-time calibration pipeline. Reads visibilities through a BlockVisibility iterator, calculates model visibilities according to a component-based sky model, and performs calibration solution, writing a gaintable for each chunk of visibilities. :param vis: Visibility or Union(Visibility, Iterable) :param components: Component-based sky model :param kwargs: Parameters :return: gaintable """ if not isinstance(vis, collections.Iterable): vis = [vis] for ichunk, vischunk in enumerate(vis): vispred = copy_visibility(vischunk, zero=True) vispred = predict_skycomponent_visibility(vispred, components) gt = solve_gaintable(vischunk, vispred, **kwargs) yield gt
def res_vis(vis, final_vis): residual_vis = copy_visibility(vis) residual_vis.data['vis'][...] = vis.data['vis'][...] - final_vis.data['vis'][...] return residual_vis
def predict_and_apply(ovis, calskymodel): tvis = copy_visibility(ovis, zero=True) tvis = predict_skymodel_visibility(tvis, calskymodel[0]) tvis = apply_gaintable(tvis, calskymodel[1]) return tvis
def predict_and_apply(ovis, modelpartition): tvis = copy_visibility(ovis, zero=True) tvis = predict_skymodel_visibility(tvis, modelpartition[0]) tvis = apply_gaintable(tvis, modelpartition[1]) return tvis