def ft_cal_sm(ov, sm): assert isinstance(ov, Visibility), ov assert isinstance(sm, SkyModel), sm v = copy_visibility(ov) v.data['vis'][...] = 0.0 + 0.0j if len(sm.components) > 0: if isinstance(sm.mask, Image): comps = copy_skycomponent(sm.components) comps = apply_beam_to_skycomponent(comps, sm.mask) v = predict_skycomponent_visibility(v, comps) else: v = predict_skycomponent_visibility(v, sm.components) if isinstance(sm.image, Image): if numpy.max(numpy.abs(sm.image.data)) > 0.0: if isinstance(sm.mask, Image): model = copy_image(sm.image) model.data *= sm.mask.data else: model = sm.image v = predict_list_serial_workflow([v], [model], context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs)[0] if docal and isinstance(sm.gaintable, GainTable): bv = convert_visibility_to_blockvisibility(v) bv = apply_gaintable(bv, sm.gaintable, inverse=True) v = convert_blockvisibility_to_visibility(bv) return v
def ift_ical_sm(v, sm, g): assert isinstance(v, Visibility) or isinstance(v, BlockVisibility), v assert isinstance(sm, SkyModel), sm if g is not None: assert len(g) == 2, g assert isinstance(g[0], Image), g[0] assert isinstance(g[1], ConvolutionFunction), g[1] if docal and isinstance(sm.gaintable, GainTable): if isinstance(v, Visibility): bv = convert_visibility_to_blockvisibility(v) bv = apply_gaintable(bv, sm.gaintable) v = convert_blockvisibility_to_visibility(bv) else: v = apply_gaintable(v, sm.gaintable) result = invert_list_serial_workflow([v], [sm.image], context=context, vis_slices=vis_slices, facets=facets, gcfcf=[g], **kwargs)[0] if isinstance(sm.mask, Image): result[0].data *= sm.mask.data return result
def corrupt_vis(vis, gt, **kwargs): if isinstance(vis, Visibility): bv = convert_visibility_to_blockvisibility(vis) else: bv = vis if gt is None: gt = create_gaintable_from_blockvisibility(bv, **kwargs) gt = simulate_gaintable(gt, seed=seed, **kwargs) bv = apply_gaintable(bv, gt) if isinstance(vis, Visibility): return convert_blockvisibility_to_visibility(bv) else: return bv
def ift_ical_sm(v, sm): assert isinstance(v, Visibility), v assert isinstance(sm.image, Image), sm.image if docal and isinstance(sm.gaintable, GainTable): bv = convert_visibility_to_blockvisibility(v) bv = apply_gaintable(bv, sm.gaintable) v = convert_blockvisibility_to_visibility(bv) result = invert_list_serial_workflow([v], [sm.image], context=context, vis_slices=vis_slices, facets=facets, gcfcf=gcfcf, **kwargs)[0] if isinstance(sm.mask, Image): result[0].data *= sm.mask.data return result
def actualSetup(self, nsources=None, nvoronoi=None): n_workers = 8 # Set up the observation: 10 minutes at transit, with 10s integration. # Skip 5/6 points to avoid outstation redundancy nfreqwin = 1 ntimes = 3 self.rmax = 2500.0 dec = -40.0 * u.deg frequency = [1e8] channel_bandwidth = [0.1e8] times = numpy.linspace(-10.0, 10.0, ntimes) * numpy.pi / (3600.0 * 12.0) phasecentre = SkyCoord(ra=+0.0 * u.deg, dec=dec, frame='icrs', equinox='J2000') low = create_named_configuration('LOWBD2', rmax=self.rmax) centre = numpy.mean(low.xyz, axis=0) distance = numpy.hypot(low.xyz[:, 0] - centre[0], low.xyz[:, 1] - centre[1], low.xyz[:, 2] - centre[2]) lowouter = low.data[distance > 1000.0][::6] lowcore = low.data[distance < 1000.0][::3] low.data = numpy.hstack((lowcore, lowouter)) blockvis = create_blockvisibility( low, times, frequency=frequency, channel_bandwidth=channel_bandwidth, weight=1.0, phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI"), zerow=True) vis = convert_blockvisibility_to_visibility(blockvis) advice = advise_wide_field(vis, guard_band_image=2.0, delA=0.02) cellsize = advice['cellsize'] npixel = advice['npixels2'] small_model = create_image_from_visibility(blockvis, npixel=512, frequency=frequency, nchan=nfreqwin, cellsize=cellsize, phasecentre=phasecentre) vis.data['imaging_weight'][...] = vis.data['weight'][...] vis = weight_list_serial_workflow([vis], [small_model])[0] vis = taper_list_serial_workflow([vis], 3 * cellsize)[0] blockvis = convert_visibility_to_blockvisibility(vis) # ### Generate the model from the GLEAM catalog, including application of the primary beam. beam = create_image_from_visibility(blockvis, npixel=npixel, frequency=frequency, nchan=nfreqwin, cellsize=cellsize, phasecentre=phasecentre) beam = create_low_test_beam(beam, use_local=False) flux_limit = 0.5 original_gleam_components = create_low_test_skycomponents_from_gleam( flux_limit=flux_limit, phasecentre=phasecentre, frequency=frequency, polarisation_frame=PolarisationFrame('stokesI'), radius=0.15) all_components = apply_beam_to_skycomponent(original_gleam_components, beam) all_components = filter_skycomponents_by_flux(all_components, flux_min=flux_limit) voronoi_components = filter_skycomponents_by_flux(all_components, flux_min=1.5) def max_flux(elem): return numpy.max(elem.flux) voronoi_components = sorted(voronoi_components, key=max_flux, reverse=True) if nsources is not None: all_components = [all_components[0]] if nvoronoi is not None: voronoi_components = [voronoi_components[0]] self.screen = import_image_from_fits( arl_path('data/models/test_mpc_screen.fits')) all_gaintables = create_gaintable_from_screen(blockvis, all_components, self.screen) gleam_skymodel_noniso = [ SkyModel(components=[all_components[i]], gaintable=all_gaintables[i]) for i, sm in enumerate(all_components) ] # ### Now predict the visibility for each skymodel and apply the gaintable for that skymodel, # returning a list of visibilities, one for each skymodel. We then sum these to obtain # the total predicted visibility. All images and skycomponents in the same skymodel # get the same gaintable applied which means that in this case each skycomponent has a separate gaintable. self.all_skymodel_noniso_vis = convert_blockvisibility_to_visibility( blockvis) ngroup = n_workers future_vis = arlexecute.scatter(self.all_skymodel_noniso_vis) chunks = [ gleam_skymodel_noniso[i:i + ngroup] for i in range(0, len(gleam_skymodel_noniso), ngroup) ] for chunk in chunks: result = predict_skymodel_list_arlexecute_workflow(future_vis, chunk, context='2d', docal=True) work_vis = arlexecute.compute(result, sync=True) for w in work_vis: self.all_skymodel_noniso_vis.data['vis'] += w.data['vis'] assert numpy.max( numpy.abs(self.all_skymodel_noniso_vis.data['vis'])) > 0.0 self.all_skymodel_noniso_blockvis = convert_visibility_to_blockvisibility( self.all_skymodel_noniso_vis) # ### Remove weaker of components that are too close (0.02 rad) idx, voronoi_components = remove_neighbouring_components( voronoi_components, 0.02) model = create_image_from_visibility(blockvis, npixel=npixel, frequency=frequency, nchan=nfreqwin, cellsize=cellsize, phasecentre=phasecentre) # Use the gaintable for the brightest component as the starting gaintable all_gaintables[0].gain[...] = numpy.conjugate( all_gaintables[0].gain[...]) all_gaintables[0].gain[...] = 1.0 + 0.0j self.theta_list = initialize_skymodel_voronoi(model, voronoi_components, all_gaintables[0])
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
def actualSetup(self, vnchan=1, doiso=True, ntimes=5, flux_limit=2.0, zerow=True, fixed=False): nfreqwin = vnchan rmax = 300.0 npixel = 512 cellsize = 0.001 frequency = numpy.linspace(0.8e8, 1.2e8, nfreqwin) if nfreqwin > 1: channel_bandwidth = numpy.array(nfreqwin * [frequency[1] - frequency[0]]) else: channel_bandwidth = [0.4e8] times = numpy.linspace(-numpy.pi / 3.0, numpy.pi / 3.0, ntimes) phasecentre = SkyCoord(ra=-60.0 * u.deg, dec=-60.0 * u.deg, frame='icrs', equinox='J2000') lowcore = create_named_configuration('LOWBD2', rmax=rmax) block_vis = create_blockvisibility( lowcore, times, frequency=frequency, channel_bandwidth=channel_bandwidth, weight=1.0, phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI"), zerow=zerow) block_vis.data['uvw'][..., 2] = 0.0 self.beam = create_image_from_visibility( block_vis, npixel=npixel, frequency=[numpy.average(frequency)], nchan=nfreqwin, channel_bandwidth=[numpy.sum(channel_bandwidth)], cellsize=cellsize, phasecentre=phasecentre) self.components = create_low_test_skycomponents_from_gleam( flux_limit=flux_limit, phasecentre=phasecentre, frequency=frequency, polarisation_frame=PolarisationFrame('stokesI'), radius=npixel * cellsize) self.beam = create_low_test_beam(self.beam) self.components = apply_beam_to_skycomponent(self.components, self.beam, flux_limit=flux_limit) self.vis = copy_visibility(block_vis, zero=True) gt = create_gaintable_from_blockvisibility(block_vis, timeslice='auto') for i, sc in enumerate(self.components): if sc.flux[0, 0] > 10: sc.flux[...] /= 10.0 component_vis = copy_visibility(block_vis, zero=True) gt = simulate_gaintable(gt, amplitude_error=0.0, phase_error=0.1, seed=None) component_vis = predict_skycomponent_visibility(component_vis, sc) component_vis = apply_gaintable(component_vis, gt) self.vis.data['vis'][...] += component_vis.data['vis'][...] # Do an isoplanatic selfcal self.model_vis = copy_visibility(self.vis, zero=True) self.model_vis = predict_skycomponent_visibility( self.model_vis, self.components) if doiso: gt = solve_gaintable(self.vis, self.model_vis, phase_only=True, timeslice='auto') self.vis = apply_gaintable(self.vis, gt, inverse=True) self.model_vis = convert_blockvisibility_to_visibility(self.model_vis) self.model_vis, _, _ = weight_visibility(self.model_vis, self.beam) self.dirty_model, sumwt = invert_list_arlexecute_workflow( self.model_vis, self.beam, context='2d') export_image_to_fits( self.dirty_model, "%s/test_modelpartition-model_dirty.fits" % self.dir) lvis = convert_blockvisibility_to_visibility(self.vis) lvis, _, _ = weight_visibility(lvis, self.beam) dirty, sumwt = invert_list_arlexecute_workflow(lvis, self.beam, context='2d') if doiso: export_image_to_fits( dirty, "%s/test_modelpartition-initial-iso-residual.fits" % self.dir) else: export_image_to_fits( dirty, "%s/test_modelpartition-initial-noiso-residual.fits" % self.dir) self.skymodels = [ SkyModel(components=[cm], fixed=fixed) for cm in self.components ]
low.xyz[:, 2] - centre[2]) lowouter = low.data[distance > 1000.0][::6] lowcore = low.data[distance < 1000.0][::3] low.data = numpy.hstack((lowcore, lowouter)) block_vis = create_blockvisibility( low, times, frequency=frequency, channel_bandwidth=channel_bandwidth, weight=1.0, phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI"), zerow=True) vis = convert_blockvisibility_to_visibility(block_vis) advice = advise_wide_field(vis, guard_band_image=2.0, delA=0.02) cellsize = advice['cellsize'] vis_slices = advice['vis_slices'] npixel = advice['npixels2'] small_model = create_image_from_visibility(block_vis, npixel=512, frequency=frequency, nchan=nfreqwin, cellsize=cellsize, phasecentre=phasecentre) vis.data['imaging_weight'][...] = vis.data['weight'][...] vis = weight_list_serial_workflow([vis], [small_model])[0]
def trial_case(results, seed=180555, context='wstack', nworkers=8, threads_per_worker=1, memory=8, processes=True, order='frequency', nfreqwin=7, ntimes=3, rmax=750.0, facets=1, wprojection_planes=1, use_dask=True, use_serial_imaging=False, flux_limit=0.3, nmajor=5, dft_threshold=1.0): """ Single trial for performance-timings Simulates visibilities from GLEAM including phase errors Makes dirty image and PSF Runs ICAL pipeline The results are in a dictionary: 'context': input - a string describing concisely the purpose of the test 'time overall', overall execution time (s) 'time create gleam', time to create GLEAM prediction graph 'time predict', time to execute GLEAM prediction graph 'time corrupt', time to corrupt data_models 'time invert', time to make dirty image 'time psf invert', time to make PSF 'time ICAL graph', time to create ICAL graph 'time ICAL', time to execute ICAL graph 'context', type of imaging e.g. 'wstack' 'nworkers', number of workers to create 'threads_per_worker', 'nnodes', Number of nodes, 'processes', 'order', Ordering of data_models 'nfreqwin', Number of frequency windows in simulation 'ntimes', Number of hour angles in simulation 'rmax', Maximum radius of stations used in simulation (m) 'facets', Number of facets in deconvolution and imaging 'wprojection_planes', Number of wprojection planes 'vis_slices', Number of visibility slices (per Visibbility) 'npixel', Number of pixels in image 'cellsize', Cellsize in radians 'seed', Random number seed 'dirty_max', Maximum in dirty image 'dirty_min', Minimum in dirty image 'psf_max', 'psf_min', 'restored_max', 'restored_min', 'deconvolved_max', 'deconvolved_min', 'residual_max', 'residual_min', 'git_info', GIT hash (not definitive since local mods are possible) :param results: Initial state :param seed: Random number seed (used in gain simulations) :param context: imaging context :param context: Type of context: '2d'|'timeslice'|'wstack' :param nworkers: Number of dask workers to use :param threads_per_worker: Number of threads per worker :param processes: Use processes instead of threads 'processes'|'threads' :param order: See simulate_list_list_arlexecute_workflow_workflowkflow :param nfreqwin: See simulate_list_list_arlexecute_workflow_workflowkflow :param ntimes: See simulate_list_list_arlexecute_workflow_workflowkflow :param rmax: See simulate_list_list_arlexecute_workflow_workflowkflow :param facets: Number of facets to use :param wprojection_planes: Number of wprojection planes to use :param use_dask: Use dask or immediate evaluation :return: results dictionary """ if use_dask: client = get_dask_Client(threads_per_worker=threads_per_worker, processes = threads_per_worker == 1, memory_limit=memory * 1024 * 1024 * 1024, n_workers=nworkers) arlexecute.set_client(client) nodes = findNodes(arlexecute.client) print("Defined %d workers on %d nodes" % (nworkers, len(nodes))) print("Workers are: %s" % str(nodes)) else: arlexecute.set_client(use_dask=use_dask) results['nnodes'] = 1 def init_logging(): logging.basicConfig(filename='pipelines-arlexecute-timings.log', filemode='a', format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', datefmt='%H:%M:%S', level=logging.INFO) init_logging() log = logging.getLogger() # Initialise logging on the workers. This appears to only work using the process scheduler. arlexecute.run(init_logging) def lprint(s): log.info(s) print(s) lprint("Starting pipelines-arlexecute-timings") numpy.random.seed(seed) results['seed'] = seed start_all = time.time() results['context'] = context results['hostname'] = socket.gethostname() results['git_hash'] = git_hash() results['epoch'] = time.strftime("%Y-%m-%d %H:%M:%S") lprint("Context is %s" % context) results['nworkers'] = nworkers results['threads_per_worker'] = threads_per_worker results['processes'] = processes results['memory'] = memory results['order'] = order results['nfreqwin'] = nfreqwin results['ntimes'] = ntimes results['rmax'] = rmax results['facets'] = facets results['wprojection_planes'] = wprojection_planes results['dft threshold'] = dft_threshold results['use_dask'] = use_dask lprint("At start, configuration is:") lprint(results) # Parameters determining scale frequency = numpy.linspace(1.0e8, 1.2e8, nfreqwin) centre = nfreqwin // 2 if nfreqwin > 1: channel_bandwidth = numpy.array(nfreqwin * [frequency[1] - frequency[0]]) else: channel_bandwidth = numpy.array([1e6]) times = numpy.linspace(-numpy.pi / 4.0, numpy.pi / 4.0, ntimes) phasecentre = SkyCoord(ra=+30.0 * u.deg, dec=-60.0 * u.deg, frame='icrs', equinox='J2000') bvis_list = simulate_list_arlexecute_workflow('LOWBD2', frequency=frequency, channel_bandwidth=channel_bandwidth, times=times, phasecentre=phasecentre, order=order, format='blockvis', rmax=rmax) lprint("****** Visibility creation ******") bvis_list = arlexecute.compute(bvis_list, sync=True) vis_list = [arlexecute.execute(convert_blockvisibility_to_visibility(bv)) for bv in bvis_list] vis_list = arlexecute.compute(vis_list, sync=True) # Find the best imaging parameters but don't bring the vis_list back here def get_wf(v): return advise_wide_field(v, guard_band_image=6.0, delA=0.1, facets=facets, wprojection_planes=wprojection_planes, oversampling_synthesised_beam=4.0) advice = arlexecute.compute(arlexecute.execute(get_wf)(vis_list[-1]), sync=True) # Deconvolution via sub-images requires 2^n npixel = advice['npixels2'] results['npixel'] = npixel cellsize = advice['cellsize'] results['cellsize'] = cellsize lprint("Image will have %d by %d pixels, cellsize = %.6f rad" % (npixel, npixel, cellsize)) # Create an empty model image model_list = [arlexecute.execute(create_image_from_visibility) (vis_list[f], npixel=npixel, cellsize=cellsize, frequency=[frequency[f]], channel_bandwidth=[channel_bandwidth[f]], polarisation_frame=PolarisationFrame("stokesI")) for f, freq in enumerate(frequency)] model_list = arlexecute.compute(model_list, sync=True) model_list = arlexecute.scatter(model_list) start = time.time() vis_list = weight_list_arlexecute_workflow(vis_list, model_list) vis_list = taper_list_arlexecute_workflow(vis_list, 0.003 * 750.0 / rmax) print("****** Starting weighting and tapering ******") vis_list = arlexecute.compute(vis_list, sync=True) end = time.time() results['time weight'] = end - start print("Weighting took %.3f seconds" % (end - start)) vis_list = arlexecute.scatter(vis_list) # Now set up the imaging parameters gcfcf_list = [None for i in range(nfreqwin)] if context == 'timeslice': vis_slices = ntimes lprint("Using timeslice with %d slices" % vis_slices) elif context == '2d': vis_slices = 1 elif context == "wprojection": wstep = advice['wstep'] nw = advice['wprojection_planes'] vis_slices = 1 support = advice['nwpixels'] results['wprojection_planes'] = nw lprint("Using wprojection with %d planes with wstep %.1f wavelengths" % (nw, wstep)) start = time.time() lprint("****** Starting W projection kernel creation ******") gcfcf_list = [arlexecute.execute(create_awterm_convolutionfunction, nout=1) (m, nw=nw, wstep=wstep, oversampling=8, support=support, use_aaf=True) for m in model_list] gcfcf_list = arlexecute.compute(gcfcf_list, sync=True) end = time.time() results['time create wprojection'] = end - start lprint("Creating W projection kernel took %.3f seconds" % (end - start)) cf_image = convert_convolutionfunction_to_image(gcfcf_list[centre][1]) cf_image.data = numpy.real(cf_image.data) export_image_to_fits(cf_image, "pipelines-arlexecute-timings-wterm-cf.fits") gcfcf_list = arlexecute.scatter(gcfcf_list) else: context = 'wstack' vis_slices = advice['vis_slices'] lprint("Using wstack with %d slices" % vis_slices) results['vis_slices'] = vis_slices # Make a skymodel from gleam, with bright sources as components and weak sources in an image lprint("****** Starting GLEAM skymodel creation ******") start = time.time() skymodel_list = [arlexecute.execute(create_low_test_skymodel_from_gleam) (npixel=npixel, cellsize=cellsize, frequency=[frequency[f]], phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI"), flux_limit=flux_limit, flux_threshold=dft_threshold, flux_max=5.0) for f, freq in enumerate(frequency)] skymodel_list = arlexecute.compute(skymodel_list, sync=True) end = time.time() lprint("GLEAM skymodel creation took %.3f seconds" % (end - start)) results['time create gleam'] = end - start lprint("****** Starting GLEAM skymodel prediction ******") start = time.time() predicted_vis_list = [predict_skymodel_list_arlexecute_workflow(vis_list[f], [skymodel_list[f]], context=context, vis_slices=vis_slices, facets=facets, gcfcf=[gcfcf_list[f]])[0] for f, freq in enumerate(frequency)] predicted_vis_list = arlexecute.compute(predicted_vis_list, sync=True) end = time.time() lprint("GLEAM skymodel prediction took %.3f seconds" % (end - start)) results['time predict gleam'] = end - start lprint("****** Starting psf image calculation ******") start = time.time() predicted_vis_list = arlexecute.scatter(predicted_vis_list) psf_list = invert_list_arlexecute_workflow(predicted_vis_list, model_list, vis_slices=vis_slices, dopsf=True, context=context, facets=facets, use_serial_invert=use_serial_imaging, gcfcf=gcfcf_list) psf, sumwt = arlexecute.compute(psf_list, sync=True)[centre] end = time.time() results['time psf invert'] = end - start lprint("PSF invert took %.3f seconds" % (end - start)) lprint("Maximum in psf image is %f, sumwt is %s" % (numpy.max(numpy.abs(psf.data)), str(sumwt))) qa = qa_image(psf) results['psf_max'] = qa.data['max'] results['psf_min'] = qa.data['min'] export_image_to_fits(psf, "pipelines-arlexecute-timings-%s-psf.fits" % context) # Make a smoothed model image for comparison # smoothed_model_list = restore_list_arlexecute_workflow(gleam_model_list, psf_list) # smoothed_model_list = arlexecute.compute(smoothed_model_list, sync=True) # smoothed_cube = image_gather_channels(smoothed_model_list) # export_image_to_fits(smoothed_cube, "pipelines-arlexecute-timings-cmodel.fits") # Create an empty model image model_list = [arlexecute.execute(create_image_from_visibility) (predicted_vis_list[f], npixel=npixel, cellsize=cellsize, frequency=[frequency[f]], channel_bandwidth=[channel_bandwidth[f]], polarisation_frame=PolarisationFrame("stokesI")) for f, freq in enumerate(frequency)] model_list = arlexecute.compute(model_list, sync=True) model_list = arlexecute.scatter(model_list) lprint("****** Starting dirty image calculation ******") start = time.time() dirty_list = invert_list_arlexecute_workflow(predicted_vis_list, model_list, vis_slices=vis_slices, context=context, facets=facets, use_serial_invert=use_serial_imaging, gcfcf=gcfcf_list) dirty, sumwt = arlexecute.compute(dirty_list, sync=True)[centre] end = time.time() results['time invert'] = end - start lprint("Dirty image invert took %.3f seconds" % (end - start)) lprint("Maximum in dirty image is %f, sumwt is %s" % (numpy.max(numpy.abs(dirty.data)), str(sumwt))) qa = qa_image(dirty) results['dirty_max'] = qa.data['max'] results['dirty_min'] = qa.data['min'] export_image_to_fits(dirty, "pipelines-arlexecute-timings-%s-dirty.fits" % context) # Corrupt the visibility for the GLEAM model lprint("****** Visibility corruption ******") start = time.time() corrupted_vis_list = corrupt_list_arlexecute_workflow(predicted_vis_list, phase_error=1.0, seed=seed) corrupted_vis_list = arlexecute.compute(corrupted_vis_list, sync=True) end = time.time() results['time corrupt'] = end - start lprint("Visibility corruption took %.3f seconds" % (end - start)) # Create the ICAL pipeline to run major cycles, starting selfcal at cycle 1. A global solution across all # frequencies (i.e. Visibilities) is performed. lprint("****** Starting ICAL ******") controls = create_calibration_controls() controls['T']['first_selfcal'] = 1 controls['T']['timescale'] = 'auto' start = time.time() ical_list = ical_list_arlexecute_workflow(corrupted_vis_list, model_imagelist=model_list, context=context, vis_slices=vis_slices, scales=[0, 3, 10], algorithm='mmclean', nmoment=3, niter=1000, fractional_threshold=0.1, threshold=0.01, nmajor=nmajor, gain=0.25, psf_support=64, deconvolve_facets=8, deconvolve_overlap=32, deconvolve_taper='tukey', timeslice='auto', global_solution=True, do_selfcal=True, calibration_context='T', controls=controls, use_serial_predict=use_serial_imaging, use_serial_invert=use_serial_imaging, gcfcf=gcfcf_list) end = time.time() results['time ICAL graph'] = end - start lprint("Construction of ICAL graph took %.3f seconds" % (end - start)) # Execute the graph start = time.time() result = arlexecute.compute(ical_list, sync=True) deconvolved, residual, restored, gaintables = result end = time.time() results['time ICAL'] = end - start lprint("ICAL graph execution took %.3f seconds" % (end - start)) qa = qa_image(deconvolved[centre]) results['deconvolved_max'] = qa.data['max'] results['deconvolved_min'] = qa.data['min'] deconvolved_cube = image_gather_channels(deconvolved) export_image_to_fits(deconvolved_cube, "pipelines-arlexecute-timings-%s-ical_deconvolved.fits" % context) qa = qa_image(residual[centre][0]) results['residual_max'] = qa.data['max'] results['residual_min'] = qa.data['min'] residual_cube = remove_sumwt(residual) residual_cube = image_gather_channels(residual_cube) export_image_to_fits(residual_cube, "pipelines-arlexecute-timings-%s-ical_residual.fits" % context) qa = qa_image(restored[centre]) results['restored_max'] = qa.data['max'] results['restored_min'] = qa.data['min'] restored_cube = image_gather_channels(restored) export_image_to_fits(restored_cube, "pipelines-arlexecute-timings-%s-ical_restored.fits" % context) # arlexecute.close() end_all = time.time() results['time overall'] = end_all - start_all lprint("At end, results are:") lprint(results) return results