def weight_list_serial_workflow(vis_list, model_imagelist, gcfcf=None, weighting='uniform', **kwargs): """ Weight the visibility data This is done collectively so the weights are summed over all vis_lists and then corrected :param vis_list: :param model_imagelist: Model required to determine weighting parameters :param weighting: Type of weighting :param kwargs: Parameters for functions in graphs :return: List of vis_graphs """ centre = len(model_imagelist) // 2 if gcfcf is None: gcfcf = [create_pswf_convolutionfunction(model_imagelist[centre])] def grid_wt(vis, model, g): if vis is not None: if model is not None: griddata = create_griddata_from_image(model) griddata = grid_weight_to_griddata(vis, griddata, g[0][1]) return griddata else: return None else: return None weight_list = [ grid_wt(vis_list[i], model_imagelist[i], gcfcf) for i in range(len(vis_list)) ] merged_weight_grid = griddata_merge_weights(weight_list) def re_weight(vis, model, gd, g): if gd is not None: if vis is not None: # Ensure that the griddata has the right axes so that the convolution # function mapping works agd = create_griddata_from_image(model) agd.data = gd[0].data vis = griddata_reweight(vis, agd, g[0][1]) return vis else: return None else: return vis return [ re_weight(v, model_imagelist[i], merged_weight_grid, gcfcf) for i, v in enumerate(vis_list) ]
def ical_list_serial_workflow(vis_list, model_imagelist, context, vis_slices=1, facets=1, gcfcf=None, calibration_context='TG', do_selfcal=True, **kwargs): """Run 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 = [create_pswf_convolutionfunction(model_imagelist[0])] psf_imagelist = invert_list_serial_workflow(vis_list, model_imagelist, dopsf=True, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) model_vislist = [copy_visibility(v, zero=True) for v in vis_list] if do_selfcal: cal_vis_list = [copy_visibility(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 model_vislist = predict_list_serial_workflow(model_vislist, model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) cal_vis_list, gt_list = calibrate_list_serial_workflow( cal_vis_list, model_vislist, calibration_context=calibration_context, **kwargs) residual_vislist = subtract_list_serial_workflow( cal_vis_list, model_vislist) residual_imagelist = invert_list_serial_workflow(residual_vislist, model_imagelist, context=context, dopsf=False, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, iteration=0, **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_serial_workflow( cal_vis_list, model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) deconvolve_model_imagelist = deconvolve_list_serial_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: model_vislist = predict_list_serial_workflow( model_vislist, deconvolve_model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) cal_vis_list = [copy_visibility(v) for v in vis_list] cal_vis_list, gt_list = calibrate_list_serial_workflow( cal_vis_list, model_vislist, calibration_context=calibration_context, iteration=cycle, **kwargs) residual_vislist = subtract_list_serial_workflow( cal_vis_list, model_vislist) residual_imagelist = invert_list_serial_workflow( residual_vislist, model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) else: residual_imagelist = residual_list_serial_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_serial_workflow( residual_imagelist, psf_imagelist, deconvolve_model_imagelist, prefix=prefix, **kwargs) residual_imagelist = residual_list_serial_workflow( cal_vis_list, deconvolve_model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) restore_imagelist = restore_list_serial_workflow( deconvolve_model_imagelist, psf_imagelist, residual_imagelist) return deconvolve_model_imagelist, residual_imagelist, restore_imagelist, gt_list
def continuum_imaging_list_serial_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 = [create_pswf_convolutionfunction(model_imagelist[0])] psf_imagelist = invert_list_serial_workflow(vis_list, model_imagelist, context=context, dopsf=True, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) residual_imagelist = residual_list_serial_workflow(vis_list, model_imagelist, context=context, gcfcf=gcfcf, vis_slices=vis_slices, facets=facets, **kwargs) deconvolve_model_imagelist = deconvolve_list_serial_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_serial_workflow( vis_list, deconvolve_model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) deconvolve_model_imagelist = deconvolve_list_serial_workflow( residual_imagelist, psf_imagelist, deconvolve_model_imagelist, prefix=prefix, **kwargs) residual_imagelist = residual_list_serial_workflow( vis_list, deconvolve_model_imagelist, context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs) restore_imagelist = restore_list_serial_workflow( deconvolve_model_imagelist, psf_imagelist, residual_imagelist) return (deconvolve_model_imagelist, residual_imagelist, restore_imagelist)
def predict_list_serial_workflow(vis_list, model_imagelist, context, vis_slices=1, facets=1, gcfcf=None, **kwargs): """Predict, iterating over both the scattered vis_list and image The visibility and image are scattered, the visibility is predicted on each part, and then the parts are assembled. :param vis_list: list of vis :param model_imagelist: Model used to determine image parameters :param vis_slices: Number of vis slices (w stack or timeslice) :param facets: Number of facets (per axis) :param context: Type of processing e.g. 2d, wstack, timeslice or facets :param gcfcg: tuple containing grid correction and convolution function :param kwargs: Parameters for functions in components :return: List of vis_lists """ assert len(vis_list) == len( model_imagelist), "Model must be the same length as the vis_list" # Predict_2d does not clear the vis so we have to do it here. vis_list = zero_list_serial_workflow(vis_list) c = imaging_context(context) vis_iter = c['vis_iterator'] predict = c['predict'] if facets % 2 == 0 or facets == 1: actual_number_facets = facets else: actual_number_facets = facets - 1 def predict_ignore_none(vis, model, g): if vis is not None: assert isinstance(vis, Visibility) or isinstance( vis, BlockVisibility), vis assert isinstance(model, Image), model return predict(vis, model, context=context, gcfcf=g, **kwargs) else: return None if gcfcf is None: gcfcf = [create_pswf_convolutionfunction(m) for m in model_imagelist] # Loop over all frequency windows if facets == 1: image_results_list = list() for ivis, sub_vis_list in enumerate(vis_list): if len(gcfcf) > 1: g = gcfcf[ivis] else: g = gcfcf[0] # Loop over sub visibility vis_predicted = copy_visibility(sub_vis_list, zero=True) for rows in vis_iter(sub_vis_list, vis_slices): row_vis = create_visibility_from_rows(sub_vis_list, rows) row_vis_predicted = predict_ignore_none( row_vis, model_imagelist[ivis], g) if row_vis_predicted is not None: vis_predicted.data['vis'][ rows, ...] = row_vis_predicted.data['vis'] image_results_list.append(vis_predicted) return image_results_list else: image_results_list = list() for ivis, sub_vis_list in enumerate(vis_list): # Create the graph to divide an image into facets. This is by reference. facet_lists = image_scatter_facets(model_imagelist[ivis], facets=facets) facet_vis_lists = list() sub_vis_lists = visibility_scatter(sub_vis_list, vis_iter, vis_slices) # Loop over sub visibility for sub_sub_vis_list in sub_vis_lists: facet_vis_results = list() # Loop over facets for facet_list in facet_lists: # Predict visibility for this subvisibility from this facet facet_vis_list = predict_ignore_none( sub_sub_vis_list, facet_list, None) facet_vis_results.append(facet_vis_list) # Sum the current sub-visibility over all facets facet_vis_lists.append(sum_predict_results(facet_vis_results)) # Sum all sub-visibilties image_results_list.append( visibility_gather(facet_vis_lists, sub_vis_list, vis_iter)) return image_results_list
def invert_list_serial_workflow(vis_list, template_model_imagelist, dopsf=False, normalize=True, facets=1, vis_slices=1, context='2d', gcfcf=None, **kwargs): """ Sum results from invert, iterating over the scattered image and vis_list :param vis_list: list of vis :param template_model_imagelist: list of template models :param dopsf: Make the PSF instead of the dirty image :param facets: Number of facets :param normalize: Normalize by sumwt :param vis_slices: Number of slices :param context: Imaging context :param gcfcg: tuple containing grid correction and convolution function :param kwargs: Parameters for functions in components :return: List of (image, sumwt) tuples, one per vis in vis_list For example:: model_list = [create_image_from_visibility (v, npixel=npixel, cellsize=cellsize, polarisation_frame=pol_frame) for v in vis_list] dirty_list = invert_list_serial_workflow(vis_list, template_model_imagelist=model_list, context='wstack', vis_slices=51) dirty, sumwt = dirty_list[centre] """ if not isinstance(template_model_imagelist, collections.abc.Iterable): template_model_imagelist = [template_model_imagelist] c = imaging_context(context) vis_iter = c['vis_iterator'] invert = c['invert'] if facets % 2 == 0 or facets == 1: actual_number_facets = facets else: actual_number_facets = max(1, (facets - 1)) def gather_image_iteration_results(results, template_model): result = create_empty_image_like(template_model) i = 0 sumwt = numpy.zeros([template_model.nchan, template_model.npol]) for dpatch in image_scatter_facets(result, facets=facets): assert i < len( results), "Too few results in gather_image_iteration_results" if results[i] is not None: assert len(results[i]) == 2, results[i] dpatch.data[...] = results[i][0].data[...] sumwt += results[i][1] i += 1 return result, sumwt def invert_ignore_none(vis, model, gg): if vis is not None: return invert(vis, model, context=context, dopsf=dopsf, normalize=normalize, gcfcf=gg, **kwargs) else: return create_empty_image_like(model), numpy.zeros( [model.nchan, model.npol]) # If we are doing facets, we need to create the gcf for each image if gcfcf is None and facets == 1: gcfcf = [create_pswf_convolutionfunction(template_model_imagelist[0])] # Loop over all vis_lists independently results_vislist = list() if facets == 1: for ivis, sub_vis_list in enumerate(vis_list): if len(gcfcf) > 1: g = gcfcf[ivis] else: g = gcfcf[0] # Iterate within each vis_list result_image = create_empty_image_like( template_model_imagelist[ivis]) result_sumwt = numpy.zeros([ template_model_imagelist[ivis].nchan, template_model_imagelist[ivis].npol ]) for rows in vis_iter(sub_vis_list, vis_slices): row_vis = create_visibility_from_rows(sub_vis_list, rows) result = invert_ignore_none(row_vis, template_model_imagelist[ivis], g) if result is not None: result_image.data += result[1][:, :, numpy.newaxis, numpy. newaxis] * result[0].data result_sumwt += result[1] result_image = normalize_sumwt(result_image, result_sumwt) results_vislist.append((result_image, result_sumwt)) else: for ivis, sub_vis_list in enumerate(vis_list): # Create the graph to divide an image into facets. This is by reference. facet_lists = image_scatter_facets(template_model_imagelist[ivis], facets=facets) # Create the graph to divide the visibility into slices. This is by copy. sub_sub_vis_lists = visibility_scatter(sub_vis_list, vis_iter, vis_slices=vis_slices) # Iterate within each vis_list vis_results = list() for sub_sub_vis_list in sub_sub_vis_lists: facet_vis_results = list() for facet_list in facet_lists: facet_vis_results.append( invert_ignore_none(sub_sub_vis_list, facet_list, None)) vis_results.append( gather_image_iteration_results( facet_vis_results, template_model_imagelist[ivis])) results_vislist.append(sum_invert_results(vis_results)) return results_vislist