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 _invert_base(self, context, extra='', fluxthreshold=1.0, positionthreshold=1.0, check_components=True): dirty = create_empty_image_like(self.model) dirty, sumwt = invert_function(self.componentvis, dirty, dopsf=False, context=context, **self.params) export_image_to_fits( dirty, '%s/test_imaging_functions_invert_%s%s_dirty.fits' % (self.dir, context, extra)) if check_components: self._checkcomponents(dirty, fluxthreshold, positionthreshold)
def _checkdirty(self, vis, context, fluxthreshold=0.3): # Make the dirty image self.params['imaginary'] = False self.params['timeslice'] = 'auto' dirty = create_empty_image_like(self.model) dirty, sumwt = invert_function(vis=vis, im=dirty, dopsf=False, normalize=True, context='2d', **self.params) export_image_to_fits( dirty, '%s/test_imaging_functions_%s_dirty.fits' % (self.dir, context)) maxabs = numpy.max(numpy.abs(dirty.data)) assert maxabs < fluxthreshold, "%s, abs max %f exceeds flux threshold" % ( context, maxabs)
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
gt = simulate_gaintable(gt, phase_error=1.0) #print("np.sum(gt.data): ", numpy.sum(gt.data['gain'])) blockvis = apply_gaintable(block_vis, gt) #print("np.sum(blockvis.data): ", numpy.sum(blockvis.data['vis'])) model = create_image_from_visibility(block_vis, npixel=npixel, frequency=[numpy.average(frequency)], nchan=1, channel_bandwidth=[numpy.sum(channel_bandwidth)], cellsize=cellsize, phasecentre=phasecentre) #print("model sum, min, max, shape: ", numpy.sum(model.data), numpy.amin(model.data), numpy.amax(model.data), model.shape) print(qa_image(model, context='Blockvis model image')) export_image_to_fits(model, '%s/imaging-blockvis_model.fits' % (results_dir)) dirty, sumwt = invert_function(predicted_vis, model, vis_slices=vis_slices, dopsf=False, context='wstack') print(qa_image(dirty, context='Dirty image')) export_image_to_fits(dirty, '%s/imaging-dirty.fits' % (results_dir)) deconvolved, residual, restored = ical(block_vis=blockvis, model=model, vis_slices=vis_slices, timeslice='auto', algorithm='hogbom', niter=1000, fractional_threshold=0.1, threshold=0.1, context='wstack', nmajor=5, gain=0.1, first_selfcal=1, global_solution=False) print(qa_image(deconvolved, context='Clean image')) export_image_to_fits(deconvolved, '%s/imaging-dask_ical_deconvolved.fits' % (results_dir))
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)
def solve_image(vis: Visibility, model: Image, components=None, context='2d', **kwargs) -> (Visibility, Image, Image): """Solve for image using deconvolve_cube and specified predict, invert This is the same as a majorcycle/minorcycle algorithm. The components are removed prior to deconvolution. See also arguments for predict, invert, deconvolve_cube functions.2d :param vis: :param model: Model image :param predict: Predict function e.g. predict_2d, predict_wstack :param invert: Invert function e.g. invert_2d, invert_wstack :return: Visibility, model """ nmajor = get_parameter(kwargs, 'nmajor', 5) log.info("solve_image: Performing %d major cycles" % nmajor) # The model is added to each major cycle and then the visibilities are # calculated from the full model vispred = copy_visibility(vis) visres = copy_visibility(vis) vispred = predict_function(vispred, model, context=context, **kwargs) if components is not None: vispred = predict_skycomponent_visibility(vispred, components) visres.data['vis'] = vis.data['vis'] - vispred.data['vis'] dirty, sumwt = invert_function(visres, model, context=context, dopsf=False, **kwargs) psf, sumwt = invert_function(visres, model, context=context, dopsf=True, **kwargs) thresh = get_parameter(kwargs, "threshold", 0.0) for i in range(nmajor): log.info("solve_image: Start of major cycle %d" % i) cc, res = deconvolve_cube(dirty, psf, **kwargs) model.data += cc.data vispred = predict_function(vispred, model, context=context, **kwargs) visres.data['vis'] = vis.data['vis'] - vispred.data['vis'] dirty, sumwt = invert_function(visres, model, context=context, dopsf=False, **kwargs) if numpy.abs(dirty.data).max() < 1.1 * thresh: log.info("Reached stopping threshold %.6f Jy" % thresh) break log.info("solve_image: End of major cycle") log.info("solve_image: End of major cycles") return visres, model, dirty