def test_deconvolve_and_restore_cube_mmclean_facets(self): self.actualSetUp(add_errors=True) dirty_imagelist = invert_list_rsexecute_workflow(self.vis_list, self.model_imagelist, context='2d', dopsf=False, normalize=True) psf_imagelist = invert_list_rsexecute_workflow(self.vis_list, self.model_imagelist, context='2d', dopsf=True, normalize=True) dirty_imagelist = rsexecute.persist(dirty_imagelist) psf_imagelist = rsexecute.persist(psf_imagelist) dec_imagelist = deconvolve_list_rsexecute_workflow(dirty_imagelist, psf_imagelist, self.model_imagelist, niter=1000, fractional_threshold=0.1, scales=[0, 3, 10], algorithm='mmclean', nmoment=3, nchan=self.freqwin, threshold=0.01, gain=0.7, deconvolve_facets=8, deconvolve_overlap=8, deconvolve_taper='tukey') dec_imagelist = rsexecute.persist(dec_imagelist) residual_imagelist = residual_list_rsexecute_workflow(self.vis_list, model_imagelist=dec_imagelist, context='2d') residual_imagelist = rsexecute.persist(residual_imagelist) restored_list = restore_list_rsexecute_workflow(model_imagelist=dec_imagelist, psf_imagelist=psf_imagelist, residual_imagelist=residual_imagelist, empty=self.model_imagelist) restored = rsexecute.compute(restored_list, sync=True)[0] if self.persist: export_image_to_fits(restored, '%s/test_imaging_%s_overlap_mmclean_restored.fits' % (self.dir, rsexecute.type()))
def calculate_residual_dft_rsexecute_workflow(sub_bvis_list, sub_components, sub_model_list, gt_list, context='2d', **kwargs): """Calculate residual image corresponding to a set of gaintables The visibility difference for a set of components for error and no error gaintables are calculated and the residual images constructed :param sum_vis: :param sub_bvis_list: List of vis (or graph) :param sub_components: List of components (or graph) :param sub_model_list: List of models (or graph) :param no_error_gt_list: List of gaintables for no error (or graph) :param context: Imaging context e.g. '2d' or 'ng' :param residual: Calculate residual visibility (True) :return: """ dft_bvis_list = predict_dft_rsexecute_workflow(sub_bvis_list, sub_components, gt_list, context=context) return sum_invert_results_rsexecute( invert_list_rsexecute_workflow(dft_bvis_list, sub_model_list, context=context, **kwargs))
def test_restored_list_facet(self): self.actualSetUp(zerow=True) centre = self.freqwin // 2 psf_image_list = invert_list_rsexecute_workflow(self.vis_list, self.model_list, context='2d', dopsf=True) residual_image_list = residual_list_rsexecute_workflow(self.vis_list, self.model_list, context='2d') restored_4facets_image_list = restore_list_rsexecute_workflow(self.model_list, psf_image_list, residual_image_list, restore_facets=4, psfwidth=1.0) restored_4facets_image_list = rsexecute.compute(restored_4facets_image_list, sync=True) restored_1facets_image_list = restore_list_rsexecute_workflow(self.model_list, psf_image_list, residual_image_list, restore_facets=1, psfwidth=1.0) restored_1facets_image_list = rsexecute.compute(restored_1facets_image_list, sync=True) if self.persist: export_image_to_fits(restored_4facets_image_list[0], '%s/test_imaging_invert_%s_restored_4facets.fits' % (self.dir, rsexecute.type())) qa = qa_image(restored_4facets_image_list[centre]) assert numpy.abs(qa.data['max'] - 99.43438263927833) < 1e-7, str(qa) assert numpy.abs(qa.data['min'] + 0.6328915148563354) < 1e-7, str(qa) restored_4facets_image_list[centre].data -= restored_1facets_image_list[centre].data if self.persist: export_image_to_fits(restored_4facets_image_list[centre], '%s/test_imaging_invert_%s_restored_4facets_error.fits' % (self.dir, rsexecute.type())) qa = qa_image(restored_4facets_image_list[centre]) assert numpy.abs(qa.data['max']) < 1e-10, str(qa)
def test_deconvolve_spectral(self): self.actualSetUp(add_errors=True) dirty_imagelist = invert_list_rsexecute_workflow(self.vis_list, self.model_imagelist, context='2d', dopsf=False, normalize=True) psf_imagelist = invert_list_rsexecute_workflow(self.vis_list, self.model_imagelist, context='2d', dopsf=True, normalize=True) dirty_imagelist = rsexecute.persist(dirty_imagelist) psf_imagelist = rsexecute.persist(psf_imagelist) deconvolved = deconvolve_list_rsexecute_workflow(dirty_imagelist, psf_imagelist, self.model_imagelist, niter=1000, fractional_threshold=0.1, scales=[0, 3, 10], threshold=0.1, gain=0.7) deconvolved = rsexecute.persist(deconvolved) deconvolved = rsexecute.compute(deconvolved, sync=True) if self.persist: export_image_to_fits(deconvolved[0], '%s/test_imaging_%s_deconvolve_spectral.fits' % (self.dir, rsexecute.type()))
def test_restored_list_noresidual(self): self.actualSetUp(zerow=True) centre = self.freqwin // 2 psf_image_list = invert_list_rsexecute_workflow(self.vis_list, self.model_list, context='2d', dopsf=True) restored_image_list = restore_list_rsexecute_workflow(self.model_list, psf_image_list, psfwidth=1.0) restored_image_list = rsexecute.compute(restored_image_list, sync=True) if self.persist: export_image_to_fits(restored_image_list[centre], '%s/test_imaging_invert_%s_restored_noresidual.fits' % (self.dir, rsexecute.type())) qa = qa_image(restored_image_list[centre]) assert numpy.abs(qa.data['max'] - 100.0) < 1e-7, str(qa) assert numpy.abs(qa.data['min']) < 1e-7, str(qa)
def _invert_base(self, context, extra='', fluxthreshold=1.0, positionthreshold=1.0, check_components=True, facets=1, vis_slices=1, gcfcf=None, **kwargs): centre = self.freqwin // 2 dirty = invert_list_rsexecute_workflow(self.vis_list, self.model_list, context=context, dopsf=False, normalize=True, facets=facets, vis_slices=vis_slices, gcfcf=gcfcf, **kwargs) dirty = rsexecute.compute(dirty, sync=True)[centre] if self.persist: export_image_to_fits(dirty[0], '%s/test_imaging_invert_%s%s_%s_dirty.fits' % (self.dir, context, extra, rsexecute.type())) assert numpy.max(numpy.abs(dirty[0].data)), "Image is empty" if check_components: self._checkcomponents(dirty[0], fluxthreshold, positionthreshold)
def continuum_imaging_list_rsexecute_workflow(vis_list, model_imagelist, context, gcfcf=None, vis_slices=1, facets=1, **kwargs): """ Create graph for the continuum imaging pipeline. Same as ICAL but with no selfcal. :param vis_list: :param model_imagelist: :param context: Imaging context :param kwargs: Parameters for functions in components :return: """ if gcfcf is None: gcfcf = [rsexecute.execute(create_pswf_convolutionfunction)(model_imagelist[0])] psf_imagelist = invert_list_rsexecute_workflow(vis_list, model_imagelist, context=context, dopsf=True, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) residual_imagelist = residual_list_rsexecute_workflow(vis_list, model_imagelist, context=context, gcfcf=gcfcf, vis_slices=vis_slices, facets=facets, **kwargs) deconvolve_model_imagelist = deconvolve_list_rsexecute_workflow(residual_imagelist, psf_imagelist, model_imagelist, prefix='cycle 0', **kwargs) nmajor = get_parameter(kwargs, "nmajor", 5) if nmajor > 1: for cycle in range(nmajor): prefix = "cycle %d" % (cycle + 1) residual_imagelist = residual_list_rsexecute_workflow(vis_list, deconvolve_model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) deconvolve_model_imagelist = deconvolve_list_rsexecute_workflow(residual_imagelist, psf_imagelist, deconvolve_model_imagelist, prefix=prefix, **kwargs) residual_imagelist = residual_list_rsexecute_workflow(vis_list, deconvolve_model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) restore_imagelist = restore_list_rsexecute_workflow(deconvolve_model_imagelist, psf_imagelist, residual_imagelist) return (deconvolve_model_imagelist, residual_imagelist, restore_imagelist)
def _predict_base(self, context='2d', extra='', fluxthreshold=1.0, facets=1, vis_slices=1, gcfcf=None, **kwargs): centre = self.freqwin // 2 vis_list = zero_list_rsexecute_workflow(self.vis_list) vis_list = predict_list_rsexecute_workflow(vis_list, self.model_list, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) vis_list = subtract_list_rsexecute_workflow(self.vis_list, vis_list) vis_list = rsexecute.compute(vis_list, sync=True) dirty = invert_list_rsexecute_workflow(vis_list, self.model_list, context=context, dopsf=False, gcfcf=gcfcf, normalize=True, vis_slices=vis_slices) dirty = rsexecute.compute(dirty, sync=True)[centre] assert numpy.max(numpy.abs(dirty[0].data)), "Residual image is empty" if self.persist: export_image_to_fits(dirty[0], '%s/test_imaging_predict_%s%s_%s_dirty.fits' % (self.dir, context, extra, rsexecute.type())) maxabs = numpy.max(numpy.abs(dirty[0].data)) assert maxabs < fluxthreshold, "Error %.3f greater than fluxthreshold %.3f " % (maxabs, fluxthreshold)
def mpccal_skymodel_list_rsexecute_workflow(visobs, model, theta_list, nmajor=10, context='2d', mpccal_progress=None, **kwargs): """Run MPC pipeline This runs the Model Partition Calibration algorithm. See SDP Memo 97 for more details, and see workflows/scripts/pipelines/mpccal_rsexecute_pipeline.py for an example of the application :param visobs: Visibility (not a list!) :param model: Model image :param theta_list: List of SkyModels i.e. theta in memo 97. :param nmajor: Number of major cycles :param context: Imaging context :param mpccal_progress: Function to display progress :return: Delayed tuple (theta_list, residual) """ psf_obs = invert_list_rsexecute_workflow([visobs], [model], context=context, dopsf=True) result = rsexecute.execute((theta_list, model)) for iteration in range(nmajor): # The E step of decoupling the data models vdatamodel_list = predict_skymodel_list_rsexecute_workflow(visobs, theta_list, context=context, docal=True, **kwargs) vdatamodel_list = crosssubtract_datamodels_skymodel_list_rsexecute_workflow(visobs, vdatamodel_list) # The M step: 1 - Update the models by deconvolving the residual image. The residual image must be calculated # from a difference of the dirty images from the data model, and the dirty images dirty_all_conv = convolve_skymodel_list_rsexecute_workflow(visobs, theta_list, context=context, docal=True, **kwargs) dirty_all_cal = invert_skymodel_list_rsexecute_workflow(vdatamodel_list, theta_list, context=context, docal=True, **kwargs) def diff_dirty(dcal, dconv): assert numpy.max(numpy.abs(dcal[0].data)) > 0.0, "before: dcal subimage is zero" dcal[0].data -= dconv[0].data assert numpy.max(numpy.abs(dcal[0].data)) > 0.0, "after: dcal subimage is zero" return dcal dirty_all_cal = [rsexecute.execute(diff_dirty, nout=1)(dirty_all_cal[i], dirty_all_conv[i]) for i in range(len(dirty_all_cal))] def make_residual(dcal, tl, it): res = create_empty_image_like(dcal[0][0]) for i, d in enumerate(dcal): assert numpy.max(numpy.abs(d[0].data)) > 0.0, "Residual subimage is zero" if tl[i].mask is None: res.data += d[0].data else: assert numpy.max(numpy.abs(tl[i].mask.data)) > 0.0, "Mask image is zero" res.data += d[0].data * tl[i].mask.data assert numpy.max(numpy.abs(res.data)) > 0.0, "Residual image is zero" # import matplotlib.pyplot as plt # from rascil.processing_components.image import show_image # show_image(res, title='MPCCAL residual image, iteration %d' % it) # plt.show() return res residual = rsexecute.execute(make_residual, nout=1)(dirty_all_cal, theta_list, iteration) deconvolved = deconvolve_list_rsexecute_workflow([(residual, 1.0)], [psf_obs[0]], [model], **kwargs) # The M step: 2 - Update the gaintables vpredicted_list = predict_skymodel_list_rsexecute_workflow(visobs, theta_list, context=context, docal=True, **kwargs) vcalibrated_list, gaintable_list = calibrate_list_rsexecute_workflow(vdatamodel_list, vpredicted_list, calibration_context='T', iteration=iteration, global_solution=False, **kwargs) if mpccal_progress is not None: theta_list = rsexecute.execute(mpccal_progress, nout=len(theta_list))(residual, theta_list, gaintable_list, iteration) theta_list = \ rsexecute.execute(update_skymodel_from_image, nout=len(theta_list))(theta_list, deconvolved[0]) theta_list = rsexecute.execute(update_skymodel_from_gaintables, nout=len(theta_list))(theta_list, gaintable_list, calibration_context='T') result = rsexecute.execute((theta_list, residual)) return result
def calculate_selfcal_residual_from_gaintables_rsexecute_workflow( sub_bvis_list, sub_components, sub_model_list, no_error_gt_list, error_gt_list, context='2d', residual=True, selfcal=True, **kwargs): """Calculate residual image corresponding to a set of gaintables, after selfcal The visibility difference for a set of components for error and no error gaintables are calculated and the residual images constructed :param sub_bvis_list: List of vis (or graph) :param sub_components: List of components (or graph) :param sub_model_list: List of models (or graph) :param no_error_gt_list: List of gaintables for no error (or graph) :param error_gt_list: List of gaintables for error (or graph) :param context: Imaging context e.g. '2d' or 'ng' :param residual: Calculate residual visibility (True) :param selfcal: Selfcalibrate? (True) :return: """ error_sm_list = [[ rsexecute.execute(SkyModel, nout=1)(components=[sub_components[i]], gaintable=error_gt_list[ibv][i]) for i, _ in enumerate(sub_components) ] for ibv, bv in enumerate(sub_bvis_list)] no_error_sm_list = [[ rsexecute.execute(SkyModel, nout=1)(components=[sub_components[i]], gaintable=no_error_gt_list[ibv][i]) for i, _ in enumerate(sub_components) ] for ibv, bv in enumerate(sub_bvis_list)] # Predict each visibility for each skymodel. We keep all the visibilities separate # and add up dirty images at the end of processing. We calibrate which applies the voltage pattern no_error_bvis_list = [ rsexecute.execute(copy_visibility, nout=1)(bvis, zero=True) for bvis in sub_bvis_list ] no_error_bvis_list = [ predict_skymodel_list_compsonly_rsexecute_workflow( no_error_bvis_list[ibv], no_error_sm_list[ibv], context=context, docal=True, **kwargs) for ibv, bvis in enumerate(no_error_bvis_list) ] error_bvis_list = [ rsexecute.execute(copy_visibility, nout=1)(bvis, zero=True) for bvis in sub_bvis_list ] error_bvis_list = [ predict_skymodel_list_compsonly_rsexecute_workflow( error_bvis_list[ibv], error_sm_list[ibv], context=context, docal=True, **kwargs) for ibv, bvis in enumerate(error_bvis_list) ] # Sum all visibilities per component so we can selfcal def sum_vis(bvis_list): bv_sum = copy_visibility(bvis_list[0], zero=True) for ibv, bv in enumerate(bvis_list): bv_sum.data['vis'] += bv.data['vis'] return bv_sum error_bvis_list = [ rsexecute.execute(sum_vis)(error_bvis_list[ibvis]) for ibvis, _ in enumerate(error_bvis_list) ] no_error_bvis_list = [ rsexecute.execute(sum_vis)(no_error_bvis_list[ibvis]) for ibvis, _ in enumerate(no_error_bvis_list) ] def selfcal_convert(error_bvis, no_error_bvis): if selfcal: gt = solve_gaintable(error_bvis, no_error_bvis, gt=None, phase_only=True, niter=30, tol=1e-8, crosspol=False, normalise_gains=True, **kwargs) error_bvis = apply_gaintable(error_bvis, gt) if residual: error_bvis.data[ 'vis'] = error_bvis.data['vis'] - no_error_bvis.data['vis'] if context != "ng": error_vis = convert_blockvisibility_to_visibility(error_bvis) return error_vis else: return error_bvis error_vis_list = [ rsexecute.execute(selfcal_convert)(error_bvis_list[ibv], no_error_bvis_list[ibv]) for ibv, _ in enumerate(error_bvis_list) ] dirty_list = invert_list_rsexecute_workflow(error_vis_list, sub_model_list, context=context, **kwargs) return dirty_list
def create_vis_list_with_errors(sub_bvis_list, sub_components, sub_model_list, vp_list, vp_coeffs, use_radec=False): # One pointing table per visibility if seed is not None: numpy.random.seed(seed) # Create the gain tables, one per Visibility and per component nants, nvp = vp_coeffs.shape no_error_vp_list = [vp_list[0]] no_error_vp_coeffs = numpy.ones([nants, 1]) no_error_gt_list = [ rsexecute.execute(simulate_gaintable_from_voltage_patterns)( bvis, sub_components, no_error_vp_list, no_error_vp_coeffs, use_radec=use_radec) for ibv, bvis in enumerate(sub_bvis_list) ] error_gt_list = [ rsexecute.execute(simulate_gaintable_from_voltage_patterns)( bvis, sub_components, vp_list, vp_coeffs, use_radec=use_radec) for ibv, bvis in enumerate(sub_bvis_list) ] if show: tmp_gt_list = rsexecute.compute(error_gt_list, sync=True) plt.clf() for gt in tmp_gt_list: amp = numpy.abs(gt[0].gain[:, 0, 0, 0, 0]) plt.plot(gt[0].time[amp > 0.0], 1.0 / amp[amp > 0.0], '.') plt.title("%s: dish 0 amplitude gain" % (basename)) plt.xlabel('Time (s)') plt.savefig('gaintable.png') plt.show(block=False) # Each component in original components becomes a separate skymodel # Inner nest is over skymodels, outer is over bvis's error_sm_list = [[ rsexecute.execute(SkyModel, nout=1)(components=[sub_components[i]], gaintable=error_gt_list[ibv][i]) for i, _ in enumerate(sub_components) ] for ibv, bv in enumerate(sub_bvis_list)] no_error_sm_list = [[ rsexecute.execute(SkyModel, nout=1)(components=[sub_components[i]], gaintable=no_error_gt_list[ibv][i]) for i, _ in enumerate(sub_components) ] for ibv, bv in enumerate(sub_bvis_list)] # Predict each visibility for each skymodel. We keep all the visibilities separate # and add up dirty images at the end of processing. We calibrate which applies the voltage pattern no_error_bvis_list = [ rsexecute.execute(copy_visibility, nout=1)(bvis, zero=True) for bvis in sub_bvis_list ] no_error_bvis_list = [ predict_skymodel_list_compsonly_rsexecute_workflow( no_error_bvis_list[ibv], no_error_sm_list[ibv], context='2d', docal=True) for ibv, bvis in enumerate(no_error_bvis_list) ] error_bvis_list = [ rsexecute.execute(copy_visibility, nout=1)(bvis, zero=True) for bvis in sub_bvis_list ] error_bvis_list = [ predict_skymodel_list_compsonly_rsexecute_workflow( error_bvis_list[ibv], error_sm_list[ibv], context='2d', docal=True) for ibv, bvis in enumerate(error_bvis_list) ] # Inner nest is bvis per skymodels, outer is over vis's. Calculate residual visibility def subtract_vis_convert(error_bvis, no_error_bvis): error_bvis.data[ 'vis'] = error_bvis.data['vis'] - no_error_bvis.data['vis'] error_vis = convert_blockvisibility_to_visibility(error_bvis) return error_vis error_vis_list = [[ rsexecute.execute(subtract_vis_convert)( error_bvis_list[ibvis][icomp], no_error_bvis_list[ibvis][icomp]) for icomp, _ in enumerate(sub_components) ] for ibvis, _ in enumerate(error_bvis_list)] # Now for each visibility/component, we make the component dirty images. We just add these # component dirty images since the weights should be the same def sum_images(images): sum_image = create_empty_image_like(images[0][0]) for im in images: sum_image.data += im[0].data return sum_image, images[0][1] dirty_list = list() for vis in error_vis_list: result = invert_list_rsexecute_workflow(vis, sub_model_list, '2d') dirty_list.append(rsexecute.execute(sum_images)(result)) return dirty_list
vis_list = weight_list_rsexecute_workflow(future_vis_list, future_psf_list) vis_list = rsexecute.compute(vis_list, sync=True) future_vis_list = rsexecute.scatter(vis_list) del vis_list bvis_list = [ rsexecute.execute(convert_visibility_to_blockvisibility)(vis) for vis in future_vis_list ] bvis_list = rsexecute.compute(bvis_list, sync=True) future_bvis_list = rsexecute.scatter(bvis_list) print("Inverting to get PSF") psf_list = invert_list_rsexecute_workflow(future_vis_list, future_psf_list, '2d', dopsf=True) psf_list = rsexecute.compute(psf_list, sync=True) psf, sumwt = sum_invert_results(psf_list) print("PSF sumwt ", sumwt) if export_images: export_image_to_fits(psf, 'PSF_rascil.fits') if show: show_image(psf, cm='gray_r', title='%s PSF' % basename, vmin=-0.01, vmax=0.1) plt.savefig('PSF_rascil.png') plt.show(block=False) del psf_list
def calculate_residual_from_gaintables_rsexecute_workflow( sub_bvis_list, sub_components, sub_model_list, no_error_gt_list, error_gt_list): """Calculate residual image corresponding to a set of gaintables The visibility difference for a set of components for error and no error gaintables are calculated and the residual images constructed :param sub_bvis_list: :param sub_components: :param sub_model_list: :param no_error_gt_list: :param error_gt_list: :return: """ error_sm_list = [[ rsexecute.execute(SkyModel, nout=1)(components=[sub_components[i]], gaintable=error_gt_list[ibv][i]) for i, _ in enumerate(sub_components) ] for ibv, bv in enumerate(sub_bvis_list)] no_error_sm_list = [[ rsexecute.execute(SkyModel, nout=1)(components=[sub_components[i]], gaintable=no_error_gt_list[ibv][i]) for i, _ in enumerate(sub_components) ] for ibv, bv in enumerate(sub_bvis_list)] # Predict each visibility for each skymodel. We keep all the visibilities separate # and add up dirty images at the end of processing. We calibrate which applies the voltage pattern no_error_bvis_list = [ rsexecute.execute(copy_visibility, nout=1)(bvis, zero=True) for bvis in sub_bvis_list ] no_error_bvis_list = [ predict_skymodel_list_compsonly_rsexecute_workflow( no_error_bvis_list[ibv], no_error_sm_list[ibv], context='2d', docal=True) for ibv, bvis in enumerate(no_error_bvis_list) ] error_bvis_list = [ rsexecute.execute(copy_visibility, nout=1)(bvis, zero=True) for bvis in sub_bvis_list ] error_bvis_list = [ predict_skymodel_list_compsonly_rsexecute_workflow( error_bvis_list[ibv], error_sm_list[ibv], context='2d', docal=True) for ibv, bvis in enumerate(error_bvis_list) ] # Inner nest is bvis per skymodels, outer is over vis's. Calculate residual visibility def subtract_vis_convert(error_bvis, no_error_bvis): error_bvis.data[ 'vis'] = error_bvis.data['vis'] - no_error_bvis.data['vis'] error_vis = convert_blockvisibility_to_visibility(error_bvis) return error_vis error_vis_list = [[ rsexecute.execute(subtract_vis_convert)( error_bvis_list[ibvis][icomp], no_error_bvis_list[ibvis][icomp]) for icomp, _ in enumerate(sub_components) ] for ibvis, _ in enumerate(error_bvis_list)] # Now for each visibility/component, we make the component dirty images. We just add these # component dirty images since the weights should be the same def sum_images(images): sum_image = create_empty_image_like(images[0][0]) for im in images: sum_image.data += im[0].data return sum_image, images[0][1] dirty_list = list() for vis in error_vis_list: result = invert_list_rsexecute_workflow(vis, sub_model_list, '2d') dirty_list.append(rsexecute.execute(sum_images)(result)) return dirty_list
def ical_list_rsexecute_workflow(vis_list, model_imagelist, context, vis_slices=1, facets=1, gcfcf=None, calibration_context='TG', do_selfcal=True, **kwargs): """Create graph for ICAL pipeline :param vis_list: :param model_imagelist: :param context: imaging context e.g. '2d' :param calibration_context: Sequence of calibration steps e.g. TGB :param do_selfcal: Do the selfcalibration? :param kwargs: Parameters for functions in components :return: """ gt_list = list() if gcfcf is None: gcfcf = [rsexecute.execute(create_pswf_convolutionfunction)(model_imagelist[0])] psf_imagelist = invert_list_rsexecute_workflow(vis_list, model_imagelist, dopsf=True, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) model_vislist = [rsexecute.execute(copy_visibility, nout=1)(v, zero=True) for v in vis_list] if do_selfcal: cal_vis_list = [rsexecute.execute(copy_visibility, nout=1)(v) for v in vis_list] else: cal_vis_list = vis_list if do_selfcal: # Make the predicted visibilities, selfcalibrate against it correcting the gains, then # form the residual visibility, then make the residual image predicted_model_vislist = predict_list_rsexecute_workflow(model_vislist, model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) recal_vis_list, gt_list = calibrate_list_rsexecute_workflow(cal_vis_list, predicted_model_vislist, calibration_context=calibration_context, **kwargs) def zero_model_image(im): log.info("ical_list_rsexecute_workflow: setting initial mode to zero after initial selfcal") im.data[...]=0.0 return im model_imagelist = [rsexecute.execute(zero_model_image, nout=1)(model) for model in model_imagelist] residual_imagelist = invert_list_rsexecute_workflow(recal_vis_list, model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) else: # If we are not selfcalibrating it's much easier and we can avoid an unnecessary round of gather/scatter # for visibility partitioning such as timeslices and wstack. residual_imagelist = residual_list_rsexecute_workflow(cal_vis_list, model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) deconvolve_model_imagelist = deconvolve_list_rsexecute_workflow(residual_imagelist, psf_imagelist, model_imagelist, prefix='cycle 0', **kwargs) nmajor = get_parameter(kwargs, "nmajor", 5) if nmajor > 1: for cycle in range(nmajor): if do_selfcal: predicted_model_vislist = predict_list_rsexecute_workflow(model_vislist, deconvolve_model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) recal_vis_list, gt_list = calibrate_list_rsexecute_workflow(cal_vis_list, predicted_model_vislist, calibration_context=calibration_context, iteration=cycle, **kwargs) residual_vislist = subtract_list_rsexecute_workflow(recal_vis_list, model_vislist) residual_imagelist = invert_list_rsexecute_workflow(residual_vislist, model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) else: residual_imagelist = residual_list_rsexecute_workflow(cal_vis_list, deconvolve_model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) prefix = "cycle %d" % (cycle + 1) deconvolve_model_imagelist = deconvolve_list_rsexecute_workflow(residual_imagelist, psf_imagelist, deconvolve_model_imagelist, prefix=prefix, **kwargs) residual_imagelist = residual_list_rsexecute_workflow(cal_vis_list, deconvolve_model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) restore_imagelist = restore_list_rsexecute_workflow(deconvolve_model_imagelist, psf_imagelist, residual_imagelist) return (deconvolve_model_imagelist, residual_imagelist, restore_imagelist, gt_list)