def calibrate_visibility(vt: Visibility, model: Image = None, components=None, predict=predict_2d, **kwargs) -> Visibility: """ calibrate Visibility with respect to model and optionally components :param vt: Visibility :param model: Model image :param components: Sky components :return: Calibrated visibility """ assert model is not None or components is not None, "calibration requires a model or skycomponents" vtpred = copy_visibility(vt, zero=True) if model is not None: vtpred = predict(vtpred, model, **kwargs) if components is not None: vtpred = predict_skycomponent_visibility(vtpred, components) else: vtpred = predict_skycomponent_visibility(vtpred, components) bvt = decoalesce_visibility(vt) bvtpred = decoalesce_visibility(vtpred) gt = solve_gaintable(bvt, bvtpred, **kwargs) bvt = apply_gaintable(bvt, gt, inverse=get_parameter(kwargs, "inverse", False)) return convert_blockvisibility_to_visibility(bvt)
def skymodel_cal_fit_skymodel(vis, calskymodel, gain=0.1, method='fit', **kwargs): """Fit a single skymodel to a visibility This is the update to the component part of the window. :param evis: Expected vis for this ssm :param calskymodel: scm element being fit i.e. (skymodel, gaintable) tuple :param gain: Gain in step :param method: 'fit' or 'sum' :param kwargs: :return: skycomponent """ cvis = convert_blockvisibility_to_visibility(vis) new_comps = list() for comp in calskymodel[0].components: new_comp = copy_skycomponent(comp) if method == 'sum': new_flux, _ = sum_visibility(cvis, new_comp.direction) new_comp.flux = gain * new_flux + (1.0 - gain) * comp[0].flux else: new_comp, _ = fit_visibility(cvis, new_comp) new_comp.flux = gain * new_comp.flux + (1.0 - gain) * comp.flux new_comps.append(new_comp) return SkyModel(components=new_comps)
def calibrate_blockvisibility(bvt: BlockVisibility, model=None, components=None, predict=predict_2d, **kwargs): """ calibrate BlockVisibility with respect to model and optionally components :param bvt: BlockVisibility :param model: Model image :param components: Sky components :returns: Calibrated BlockVisibility """ assert model is not None or components is not None, "calibration requires a model or skycomponents" if model is not None: vtpred = convert_blockvisibility_to_visibility(bvt) vtpred = predict(vtpred, model, **kwargs) bvtpred = decoalesce_visibility(vtpred) if components is not None: bvtpred = predict_skycomponent_blockvisibility(bvtpred, components) else: bvtpred = copy_visibility(bvt, zero=True) bvtpred = predict_skycomponent_blockvisibility(bvtpred, components) gt = solve_gaintable(bvt, bvtpred, **kwargs) return apply_gaintable(bvt, gt, **kwargs)
def test_convert_decoalesce_zero(self): cvis = convert_blockvisibility_to_visibility(self.blockvis) assert numpy.min(cvis.frequency) == numpy.min(self.frequency) assert numpy.min(cvis.frequency) > 0.0 dvis = decoalesce_visibility(cvis) assert dvis.nvis == self.blockvis.nvis dvis = decoalesce_visibility(cvis, overwrite=True) assert dvis.nvis == self.blockvis.nvis
def test_coalesce_decoalesce_with_iter(self): for rows in vis_timeslice_iter(self.blockvis): visslice = create_visibility_from_rows(self.blockvis, rows) cvisslice = convert_blockvisibility_to_visibility(visslice) assert numpy.min(cvisslice.frequency) == numpy.min(self.frequency) assert numpy.min(cvisslice.frequency) > 0.0 dvisslice = decoalesce_visibility(cvisslice) assert dvisslice.nvis == visslice.nvis
def test_convert_blockvisibility(self): self.vis = create_blockvisibility( self.lowcore, self.times, self.frequency, phasecentre=self.phasecentre, weight=1.0, channel_bandwidth=self.channel_bandwidth) vis = convert_blockvisibility_to_visibility(self.vis) assert vis.nvis == len(vis.time) assert numpy.unique(vis.time).size == self.vis.time.size
def calibrate_function(vis, model_vis, context='T', controls=None, iteration=0, **kwargs): """ Calibrate using algorithm specified by context The context string can denote a sequence of calibrations e.g. TGB with different timescales. :param vis: :param model_vis: :param context: calibration contexts in order of correction e.g. 'TGB' :param control: controls dictionary, modified as necessary :param iteration: Iteration number to be compared to the 'first_selfcal' field. :param kwargs: :return: Calibrated data, dict(gaintables) """ gaintables = {} if controls is None: controls = create_calibration_controls(**kwargs) isVis = isinstance(vis, Visibility) if isVis: avis = convert_visibility_to_blockvisibility(vis) else: avis = vis isMVis = isinstance(model_vis, Visibility) if isMVis: amvis = convert_visibility_to_blockvisibility(model_vis) else: amvis = model_vis for c in context: if iteration >= controls[c]['first_selfcal']: gaintables[c] = \ create_gaintable_from_blockvisibility(avis, timeslice=controls[c]['timeslice']) gaintables[c] = solve_gaintable(avis, amvis, timeslice=controls[c]['timeslice'], phase_only=controls[c]['phase_only'], crosspol=controls[c]['shape'] == 'matrix') log.debug('calibrate_function: Jones matrix %s, iteration %d' % (c, iteration)) log.debug(qa_gaintable(gaintables[c], context='Jones matrix %s, iteration %d' % (c, iteration))) avis = apply_gaintable(avis, gaintables[c], inverse=True, timeslice=controls[c]['timeslice']) else: log.debug('calibrate_function: Jones matrix %s not solved, iteration %d' % (c, iteration)) if isVis: return convert_blockvisibility_to_visibility(avis), gaintables else: return avis, gaintables
def test_sagecal_solve_delayed(self): self.actualSetup() sagecal_graph = create_sagecal_solve_graph(self.vis, self.components, niter=30, gain=0.25, tol=1e-8) sagecal_graph.visualize("%s/sagecal.svg" % self.dir) thetas, residual_vis = sagecal_graph.compute() residual_vis = convert_blockvisibility_to_visibility(residual_vis) residual_vis, _, _ = weight_visibility(residual_vis, self.beam) dirty, sumwt = invert_function(residual_vis, self.beam, context='2d') export_image_to_fits(dirty, "%s/test_sagecal-delayed-final_residual.fits" % self.dir) qa = qa_image(dirty) assert qa.data['rms'] < 4e-3, qa
def test_sagecal_solve(self): self.actualSetup() thetas, residual_vis = sagecal_solve(self.vis, self.components, niter=30, gain=0.25, tol=1e-8) residual_vis = convert_blockvisibility_to_visibility(residual_vis) residual_vis, _, _ = weight_visibility(residual_vis, self.beam) dirty, sumwt = invert_function(residual_vis, self.beam, context='2d') export_image_to_fits(dirty, "%s/test_sagecal-final_residual.fits" % self.dir) # for i, theta in enumerate(thetas): # print('Component %d, original flux = %s, recovered flux = %s, gain residual = %s' % # (i, str(self.components[i].flux[0, 0]), str(theta[0].flux[0, 0]), # str(numpy.max(theta[1].residual)))) # qa = qa_image(dirty) assert qa.data['rms'] < 4e-3, qa
def sagecal_fit_component(evis, theta, gain=0.1, method='fit', **kwargs): """Fit a single component to a visibility i.e. A13 This is the update to the component part of the window :param evis: :param theta: :param kwargs: :return: """ cvis = convert_blockvisibility_to_visibility(evis) new_comp = copy_skycomponent(theta[0]) if method == 'sum': new_flux, _ = sum_visibility(cvis, new_comp.direction) new_comp.flux = gain * new_flux + (1.0 - gain) * theta[0].flux else: new_comp, _ = fit_visibility(cvis, new_comp) new_comp.flux = gain * new_comp.flux + (1.0 - gain) * theta[0].flux return new_comp
def trial_case(results, seed=180555, context='wstack', nworkers=8, threads_per_worker=1, processes=True, order='frequency', nfreqwin=7, ntimes=3, rmax=750.0, facets=1, wprojection_planes=1): """ 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 '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 '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 create_simulate_vis_graph :param nfreqwin: See create_simulate_vis_graph :param ntimes: See create_simulate_vis_graph :param rmax: See create_simulate_vis_graph :param facets: Number of facets to use :param wprojection_planes: Number of wprojection planes to use :param kwargs: :return: results dictionary """ def check_workers(client, nworkers_initial): nworkers_final = len(client.scheduler_info()['workers']) assert nworkers_final == nworkers_initial, "Started %d workers, only %d at end" % \ (nworkers_initial, nworkers_final) 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") zerow = False print("Context is %s" % context) results['nworkers'] = nworkers results['threads_per_worker'] = threads_per_worker results['processes'] = processes results['order'] = order results['nfreqwin'] = nfreqwin results['ntimes'] = ntimes results['rmax'] = rmax results['facets'] = facets results['wprojection_planes'] = wprojection_planes print("At start, configuration is {0!r}".format(results)) # Parameters determining scale frequency = numpy.linspace(0.8e8, 1.2e8, nfreqwin) if nfreqwin > 1: channel_bandwidth = numpy.array(nfreqwin * [frequency[1] - frequency[0]]) else: channel_bandwidth = numpy.array([1e6]) times = numpy.linspace(-numpy.pi / 3.0, numpy.pi / 3.0, ntimes) phasecentre = SkyCoord(ra=+30.0 * u.deg, dec=-60.0 * u.deg, frame='icrs', equinox='J2000') vis_graph_list = create_simulate_vis_graph( 'LOWBD2', frequency=frequency, channel_bandwidth=channel_bandwidth, times=times, phasecentre=phasecentre, order=order, format='blockvis', rmax=rmax) client = get_dask_Client(n_workers=nworkers, threads_per_worker=threads_per_worker, processes=processes) nworkers_initial = len(client.scheduler_info()['workers']) check_workers(client, nworkers_initial) results['nnodes'] = len(numpy.unique(findNodes(client))) print("Defined %d workers on %d nodes" % (nworkers, results['nnodes'])) print("****** Visibility creation ******") vis_graph_list = compute_list(client, vis_graph_list) print("After creating vis_graph_list", client) # Find the best imaging parameters. wprojection_planes = 1 advice = advise_wide_field(convert_blockvisibility_to_visibility( vis_graph_list[0]), guard_band_image=6.0, delA=0.02, facets=facets, wprojection_planes=wprojection_planes, oversampling_synthesised_beam=4.0) kernel = advice['kernel'] npixel = advice['npixels2'] cellsize = advice['cellsize'] if context == 'timeslice': vis_slices = ntimes elif context == '2d': vis_slices = 1 kernel = '2d' else: vis_slices = advice['vis_slices'] results['vis_slices'] = vis_slices results['cellsize'] = cellsize results['npixel'] = npixel gleam_model_graph = [ delayed(create_low_test_image_from_gleam)( npixel=npixel, frequency=[frequency[f]], channel_bandwidth=[channel_bandwidth[f]], cellsize=cellsize, phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI"), flux_limit=0.1, applybeam=True) for f, freq in enumerate(frequency) ] start = time.time() print("****** Starting GLEAM model creation ******") gleam_model_graph = compute_list(client, gleam_model_graph) cmodel = smooth_image(gleam_model_graph[0]) export_image_to_fits(cmodel, "pipelines-timings-delayed-gleam_cmodel.fits") end = time.time() results['time create gleam'] = end - start print("Creating GLEAM model took %.2f seconds" % (end - start)) vis_graph_list = create_predict_graph(vis_graph_list, gleam_model_graph, vis_slices=51, context=context, kernel=kernel) start = time.time() print("****** Starting GLEAM model visibility prediction ******") vis_graph_list = compute_list(client, vis_graph_list) end = time.time() results['time predict'] = end - start print("After prediction", client) print("GLEAM model Visibility prediction took %.2f seconds" % (end - start)) # Corrupt the visibility for the GLEAM model print("****** Visibility corruption ******") vis_graph_list = create_corrupt_vis_graph(vis_graph_list, phase_error=1.0) start = time.time() vis_graph_list = compute_list(client, vis_graph_list) end = time.time() results['time corrupt'] = end - start print("After corrupt", client) print("Visibility corruption took %.2f seconds" % (end - start)) # Create an empty model image model_graph = [ delayed(create_image_from_visibility)( vis_graph_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_graph = client.compute(model_graph, sync=True) psf_graph = create_invert_graph(vis_graph_list, model_graph, vis_slices=vis_slices, context=context, facets=facets, dopsf=True, kernel=kernel) start = time.time() print("****** Starting PSF calculation ******") psf, sumwt = client.compute(psf_graph, sync=True)[0] check_workers(client, nworkers_initial) end = time.time() results['time psf invert'] = end - start print("PSF invert took %.2f seconds" % (end - start)) print("After psf", client) results['psf_max'] = qa_image(psf).data['max'] results['psf_min'] = qa_image(psf).data['min'] dirty_graph = create_invert_graph(vis_graph_list, model_graph, vis_slices=vis_slices, context=context, facets=facets, kernel=kernel) start = time.time() print("****** Starting dirty image calculation ******") dirty, sumwt = client.compute(dirty_graph, sync=True)[0] check_workers(client, nworkers_initial) end = time.time() print("After dirty image", client) results['time invert'] = end - start print("Dirty image invert took %.2f seconds" % (end - start)) print("Maximum in dirty image is ", numpy.max(numpy.abs(dirty.data)), ", sumwt is ", sumwt) qa = qa_image(dirty) results['dirty_max'] = qa.data['max'] results['dirty_min'] = qa.data['min'] # Create the ICAL pipeline to run 5 major cycles, starting selfcal at cycle 1. A global solution across all # frequencies (i.e. Visibilities) is performed. start = time.time() print("****** Starting ICAL ******") start = time.time() ical_graph = create_ical_pipeline_graph(vis_graph_list, model_graph=model_graph, context=context, do_selfcal=1, nchan=nfreqwin, vis_slices=vis_slices, algorithm='mmclean', nmoments=3, niter=1000, fractional_threshold=0.1, scales=[0, 3, 10], threshold=0.1, nmajor=5, gain=0.7, timeslice='auto', global_solution=True, window_shape='quarter') end = time.time() results['time ICAL graph'] = end - start print("Construction of ICAL graph took %.2f seconds" % (end - start)) # Execute the graph start = time.time() result = client.compute(ical_graph, sync=True) deconvolved, residual, restored = result check_workers(client, nworkers_initial) end = time.time() print("After ICAL", client) results['time ICAL'] = end - start print("ICAL graph execution took %.2f seconds" % (end - start)) qa = qa_image(deconvolved[0]) results['deconvolved_max'] = qa.data['max'] results['deconvolved_min'] = qa.data['min'] export_image_to_fits(deconvolved[0], "pipelines-timings-delayed-ical_deconvolved.fits") qa = qa_image(residual[0][0]) results['residual_max'] = qa.data['max'] results['residual_min'] = qa.data['min'] export_image_to_fits(residual[0][0], "pipelines-timings-delayed-ical_residual.fits") qa = qa_image(restored[0]) results['restored_max'] = qa.data['max'] results['restored_min'] = qa.data['min'] export_image_to_fits(restored[0], "pipelines-timings-delayed-ical_restored.fits") # client.shutdown() end_all = time.time() results['time overall'] = end_all - start_all print("At end, results are {0!r}".format(results)) return results
def ical(block_vis: BlockVisibility, model: Image, components=None, context='2d', controls=None, **kwargs): """ Post observation image, deconvolve, and self-calibrate :param vis: :param model: Model image :param components: Initial components :param context: Imaging context :param controls: Calibration controls dictionary :return: model, residual, restored """ nmajor = get_parameter(kwargs, 'nmajor', 5) log.info("ical: Performing %d major cycles" % nmajor) do_selfcal = get_parameter(kwargs, "do_selfcal", False) if controls is None: controls = create_calibration_controls(**kwargs) # The model is added to each major cycle and then the visibilities are # calculated from the full model vis = convert_blockvisibility_to_visibility(block_vis) block_vispred = copy_visibility(block_vis, zero=True) vispred = convert_blockvisibility_to_visibility(block_vispred) vispred.data['vis'][...] = 0.0 visres = copy_visibility(vispred) vispred = predict_function(vispred, model, context=context, **kwargs) if components is not None: vispred = predict_skycomponent_visibility(vispred, components) if do_selfcal: vis, gaintables = calibrate_function(vis, vispred, 'TGB', controls, iteration=-1) visres.data['vis'] = vis.data['vis'] - vispred.data['vis'] dirty, sumwt = invert_function(visres, model, context=context, **kwargs) log.info("Maximum in residual image is %.6f" % (numpy.max(numpy.abs(dirty.data)))) psf, sumwt = invert_function(visres, model, dopsf=True, context=context, **kwargs) thresh = get_parameter(kwargs, "threshold", 0.0) for i in range(nmajor): log.info("ical: Start of major cycle %d of %d" % (i, nmajor)) cc, res = deconvolve_cube(dirty, psf, **kwargs) model.data += cc.data vispred.data['vis'][...] = 0.0 vispred = predict_function(vispred, model, context=context, **kwargs) if do_selfcal: vis, gaintables = calibrate_function(vis, vispred, 'TGB', controls, iteration=i) visres.data['vis'] = vis.data['vis'] - vispred.data['vis'] dirty, sumwt = invert_function(visres, model, context=context, **kwargs) log.info("Maximum in residual image is %s" % (numpy.max(numpy.abs(dirty.data)))) if numpy.abs(dirty.data).max() < 1.1 * thresh: log.info("ical: Reached stopping threshold %.6f Jy" % thresh) break log.info("ical: End of major cycle") log.info("ical: End of major cycles") restored = restore_cube(model, psf, dirty, **kwargs) return model, dirty, restored
def advise_wide_field(vis: Visibility, delA=0.02, oversampling_synthesised_beam=3.0, guard_band_image=6.0, facets=1, wprojection_planes=1): """ Advise on parameters for wide field imaging. Calculate sampling requirements on various parameters For example:: advice = advise_wide_field(vis, delA) wstep = get_parameter(kwargs, 'wstep', advice['w_sampling_primary_beam']) :param vis: :param delA: Allowed coherence loss (def: 0.02) :param oversampling_synthesised_beam: Oversampling of the synthesized beam (def: 3.0) :param guard_band_image: Number of primary beam half-widths-to-half-maximum to image (def: 6) :param facets: Number of facets on each axis :param wprojection_planes: Number of planes in wprojection :return: dict of advice """ if isinstance(vis, BlockVisibility): svis = convert_blockvisibility_to_visibility(vis) else: svis = vis assert isinstance(svis, Visibility), svis max_wavelength = constants.c.to('m/s').value / numpy.min(svis.frequency) log.info("advise_wide_field: Maximum wavelength %.3f (meters)" % (max_wavelength)) min_wavelength = constants.c.to('m/s').value / numpy.max(svis.frequency) log.info("advise_wide_field: Minimum wavelength %.3f (meters)" % (min_wavelength)) maximum_baseline = numpy.max(numpy.abs(svis.uvw)) # Wavelengths if isinstance(svis, BlockVisibility): maximum_baseline = maximum_baseline / min_wavelength log.info("advise_wide_field: Maximum baseline %.1f (wavelengths)" % (maximum_baseline)) diameter = numpy.min(svis.configuration.diameter) log.info("advise_wide_field: Station/antenna diameter %.1f (meters)" % (diameter)) primary_beam_fov = max_wavelength / diameter log.info("advise_wide_field: Primary beam %s" % (rad_and_deg(primary_beam_fov))) image_fov = primary_beam_fov * guard_band_image log.info("advise_wide_field: Image field of view %s" % (rad_and_deg(image_fov))) facet_fov = primary_beam_fov * guard_band_image / facets if facets > 1: log.info("advise_wide_field: Facet field of view %s" % (rad_and_deg(facet_fov))) synthesized_beam = 1.0 / (maximum_baseline) log.info("advise_wide_field: Synthesized beam %s" % (rad_and_deg(synthesized_beam))) cellsize = synthesized_beam / oversampling_synthesised_beam log.info("advise_wide_field: Cellsize %s" % (rad_and_deg(cellsize))) def pwr23(n): ex = numpy.ceil(numpy.log(n) / numpy.log(2.0)).astype('int') best = numpy.power(2, ex) if best * 3 // 4 >= n: best = best * 3 // 4 return best npixels = int(round(image_fov / cellsize)) log.info("advice_wide_field: Npixels per side = %d" % (npixels)) npixels2 = pwr23(npixels) log.info("advice_wide_field: Npixels (power of 2, 3) per side = %d" % (npixels2)) # Following equation is from Cornwell, Humphreys, and Voronkov (2012) (equation 24) # We will assume that the constraint holds at one quarter the entire FOV i.e. that # the full field of view includes the entire primary beam w_sampling_image = numpy.sqrt(2.0 * delA) / (numpy.pi * image_fov**2) log.info( "advice_wide_field: W sampling for full image = %.1f (wavelengths)" % (w_sampling_image)) if facets > 1: w_sampling_facet = numpy.sqrt(2.0 * delA) / (numpy.pi * facet_fov**2) log.info( "advice_wide_field: W sampling for facet = %.1f (wavelengths)" % (w_sampling_facet)) w_sampling_primary_beam = numpy.sqrt( 2.0 * delA) / (numpy.pi * primary_beam_fov**2) log.info( "advice_wide_field: W sampling for primary beam = %.1f (wavelengths)" % (w_sampling_primary_beam)) time_sampling_image = 86400.0 * w_sampling_image / (numpy.pi * maximum_baseline) log.info("advice_wide_field: Time sampling for full image = %.1f (s)" % (time_sampling_image)) if facets > 1: time_sampling_facet = 86400.0 * w_sampling_facet / (numpy.pi * maximum_baseline) log.info("advice_wide_field: Time sampling for facet = %.1f (s)" % (time_sampling_facet)) time_sampling_primary_beam = 86400.0 * w_sampling_primary_beam / ( numpy.pi * maximum_baseline) log.info("advice_wide_field: Time sampling for primary beam = %.1f (s)" % (time_sampling_primary_beam)) freq_sampling_image = numpy.max( vis.frequency) * w_sampling_image / (numpy.pi * maximum_baseline) log.info( "advice_wide_field: Frequency sampling for full image = %.1f (Hz)" % (freq_sampling_image)) if facets > 1: freq_sampling_facet = numpy.max( vis.frequency) * w_sampling_facet / (numpy.pi * maximum_baseline) log.info( "advice_wide_field: Frequency sampling for facet = %.1f (Hz)" % (freq_sampling_facet)) freq_sampling_primary_beam = numpy.max( vis.frequency) * w_sampling_primary_beam / (numpy.pi * maximum_baseline) log.info( "advice_wide_field: Frequency sampling for primary beam = %.1f (Hz)" % (freq_sampling_primary_beam)) wstep = w_sampling_primary_beam vis_slices = max(1, int(maximum_baseline / (wstep * wprojection_planes))) log.info('advice_wide_field: Number of planes in w stack %d' % (vis_slices)) log.info('advice_wide_field: Number of planes in w projection %d' % wprojection_planes) if wprojection_planes > 1: log.info( 'advice_wide_field: Recommend that wprojection gridding is used') kernel = 'wprojection' else: log.info( 'advice_wide_field: Recommend that 2d gridding (i.e. no wprojection) is used' ) kernel = '2d' return locals()
def actualSetup(self, sky_pol_frame='stokesI', data_pol_frame='stokesI', f=None, vnchan=1, doiso=True, ntimes=1, flux_limit=18.0): nfreqwin = vnchan ntimes = ntimes rmax = 300.0 npixel = 1024 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=+0.0 * u.deg, dec=-45.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")) 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 / 100.0) print("Number of components %d" % len(self.components)) 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 print('Component %d, flux = %s' % (i, str(sc.flux[0, 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_function(self.model_vis, self.beam, context='2d') export_image_to_fits(self.dirty_model, "%s/test_sagecal-model_dirty.fits" % self.dir) lvis = convert_blockvisibility_to_visibility(self.vis) lvis, _, _ = weight_visibility(lvis, self.beam) dirty, sumwt = invert_function(lvis, self.beam, context='2d') print(qa_image(dirty)) export_image_to_fits(dirty, "%s/test_sagecal-initial_dirty.fits" % self.dir)