def core_solve(self, spf, dpf, phase_error=0.1, amplitude_error=0.0, leakage=0.0, phase_only=True, niter=200, crosspol=False, residual_tol=1e-6, f=[100.0, 50.0, -10.0, 40.0]): self.actualSetup(spf, dpf, f=f) gt = create_gaintable_from_blockvisibility(self.vis) log.info("Created gain table: %s" % (gaintable_summary(gt))) gt = simulate_gaintable(gt, phase_error=phase_error, amplitude_error=amplitude_error, leakage=leakage) original = copy_visibility(self.vis) vis = apply_gaintable(self.vis, gt) gtsol = solve_gaintable(self.vis, original, phase_only=phase_only, niter=niter, crosspol=crosspol, tol=1e-6) vis = apply_gaintable(vis, gtsol, inverse=True) residual = numpy.max(gtsol.residual) assert residual < residual_tol, "%s %s Max residual = %s" % (spf, dpf, residual) log.debug(qa_gaintable(gt)) assert numpy.max(numpy.abs(gtsol.gain - 1.0)) > 0.1
def test_calibrate_function(self): self.actualSetup('stokesI', 'stokesI', f=[100.0]) # Prepare the corrupted visibility data gt = create_gaintable_from_blockvisibility(self.vis) log.info("Created gain table: %s" % (gaintable_summary(gt))) gt = simulate_gaintable(gt, phase_error=10.0, amplitude_error=0.1, timeslice='auto') bgt = simulate_gaintable(gt, phase_error=0.1, amplitude_error=0.01, timeslice=1e5) original = copy_visibility(self.vis) self.vis = apply_gaintable(self.vis, bgt, timeslice=1e5) self.vis = apply_gaintable(self.vis, gt, timeslice='auto') # Now get the control dictionary and calibrate controls = create_calibration_controls() controls['T']['first_selfcal'] = 0 controls['B']['first_selfcal'] = 0 calibrated_vis, gaintables = calibrate_function(self.vis, original, context='TB', controls=controls) residual = numpy.max(gaintables['T'].residual) assert residual < 3e-2, "Max T residual = %s" % (residual) residual = numpy.max(gaintables['B'].residual) assert residual < 6e-5, "Max B residual = %s" % (residual)
def ingest_visibility(self, freq=None, chan_width=None, times=None, reffrequency=None, add_errors=False, block=True): if freq is None: freq = [1e8] if times is None: ntimes = 5 times = numpy.linspace(-numpy.pi / 3.0, numpy.pi / 3.0, ntimes) if chan_width is None: chan_width = [1e6] if reffrequency is None: reffrequency = [1e8] lowcore = create_named_configuration('LOWBD2-CORE') frequency = numpy.array([freq]) channel_bandwidth = numpy.array([chan_width]) phasecentre = SkyCoord(ra=+180.0 * u.deg, dec=-60.0 * u.deg, frame='icrs', equinox='J2000') if block: vt = create_blockvisibility(lowcore, times, frequency, channel_bandwidth=channel_bandwidth, weight=1.0, phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI")) else: vt = create_visibility(lowcore, times, frequency, channel_bandwidth=channel_bandwidth, weight=1.0, phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI")) cellsize = 0.001 model = create_image_from_visibility(vt, npixel=self.npixel, cellsize=cellsize, npol=1, frequency=reffrequency, phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI")) flux = numpy.array([[100.0]]) facets = 4 rpix = model.wcs.wcs.crpix - 1.0 spacing_pixels = self.npixel // facets centers = [-1.5, -0.5, 0.5, 1.5] comps = list() for iy in centers: for ix in centers: p = int(round(rpix[0] + ix * spacing_pixels * numpy.sign(model.wcs.wcs.cdelt[0]))), \ int(round(rpix[1] + iy * spacing_pixels * numpy.sign(model.wcs.wcs.cdelt[1]))) sc = pixel_to_skycoord(p[0], p[1], model.wcs, origin=1) comp = create_skycomponent(flux=flux, frequency=frequency, direction=sc, polarisation_frame=PolarisationFrame("stokesI")) comps.append(comp) if block: predict_skycomponent_blockvisibility(vt, comps) else: predict_skycomponent_visibility(vt, comps) insert_skycomponent(model, comps) self.model = copy_image(model) self.empty_model = create_empty_image_like(model) export_image_to_fits(model, '%s/test_pipeline_bags_model.fits' % self.dir) if add_errors: # These will be the same for all calls numpy.random.seed(180555) gt = create_gaintable_from_blockvisibility(vt) gt = simulate_gaintable(gt, phase_error=1.0, amplitude_error=0.0) vt = apply_gaintable(vt, gt) return vt
def test_create_gaintable_from_rows_makecopy(self): self.actualSetup('stokesIQUV', 'linear') gt = create_gaintable_from_blockvisibility(self.vis, timeslice='auto') rows = gt.time > 150.0 for makecopy in [True, False]: selected_gt = create_gaintable_from_rows(gt, rows, makecopy=makecopy) assert selected_gt.ntimes == numpy.sum(numpy.array(rows))
def insert_unittest_errors(vt, seed=180555): """Simulate gain errors and apply :param vt: :param phase_error: :param amplitude_error: :return: """ numpy.random.seed(seed) controls = create_calibration_controls() amp_errors = {'T': 0.0, 'G': 0.01, 'B': 0.01} phase_errors = {'T': 1.0, 'G': 0.1, 'B': 0.01} for c in "TGB": gaintable = \ create_gaintable_from_blockvisibility(vt, timeslice=controls[c]['timeslice']) gaintable = simulate_gaintable( gaintable, timeslice=controls[c]['timeslice'], phase_only=controls[c]['phase_only'], crosspol=controls[c]['shape'] == 'matrix', phase_error=phase_errors[c], amplitude_error=amp_errors[c]) vt = apply_gaintable(vt, gaintable, inverse=True, timeslice=controls[c]['timeslice']) return vt
def solve_gaintable(vis: BlockVisibility, modelvis: BlockVisibility = None, gt=None, phase_only=True, niter=30, tol=1e-8, crosspol=False, **kwargs) -> GainTable: """Solve a gain table by fitting an observed visibility to a model visibility If modelvis is None, a point source model is assumed. :param vis: BlockVisibility containing the observed data :param modelvis: BlockVisibility containing the visibility predicted by a model :param gt: Existing gaintable :param phase_only: Solve only for the phases (default=True) :param niter: Number of iterations (default 30) :param tol: Iteration stops when the fractional change in the gain solution is below this tolerance :param crosspol: Do solutions including cross polarisations i.e. XY, YX or RL, LR :return: GainTable containing solution """ assert isinstance(vis, BlockVisibility), vis if modelvis is not None: assert isinstance(modelvis, BlockVisibility), modelvis if phase_only: log.debug('solve_gaintable: Solving for phase only') else: log.debug('solve_gaintable: Solving for complex gain') if gt is None: log.debug("solve_gaintable: creating new gaintable") gt = create_gaintable_from_blockvisibility(vis, **kwargs) else: log.debug("solve_gaintable: starting from existing gaintable") for row in range(gt.ntimes): vis_rows = numpy.abs(vis.time - gt.time[row]) < gt.interval[row] / 2.0 if numpy.sum(vis_rows) > 0: subvis = create_visibility_from_rows(vis, vis_rows) if modelvis is not None: model_subvis = create_visibility_from_rows(modelvis, vis_rows) pointvis = divide_visibility(subvis, model_subvis) x = numpy.sum(pointvis.vis * pointvis.weight, axis=0) xwt = numpy.sum(pointvis.weight, axis=0) else: x = numpy.sum(subvis.vis * subvis.weight, axis=0) xwt = numpy.sum(subvis.weight, axis=0) mask = numpy.abs(xwt) > 0.0 x_shape = x.shape x[mask] = x[mask] / xwt[mask] x[~mask] = 0.0 x = x.reshape(x_shape) gt = solve_from_X(gt, x, xwt, row, crosspol, niter, phase_only, tol, npol=vis.polarisation_frame.npol) assert isinstance(gt, GainTable), "gt is not a GainTable: %r" % gt assert_vis_gt_compatible(vis, gt) return gt
def actualSetUp(self, times=None): if times is not None: self.times = times self.vis = create_blockvisibility(self.lowcore, self.times, self.frequency, channel_bandwidth=self.channel_bandwidth, phasecentre=self.phasecentre, weight=1.0) self.gaintable = create_gaintable_from_blockvisibility(self.vis, time_slice='auto')
def test_create_gaintable_from_other(self): for timeslice in [10.0, 'auto', 1e5]: for spf, dpf in [('stokesIQUV', 'linear')]: self.actualSetup(spf, dpf) gt = create_gaintable_from_blockvisibility(self.vis, timeslice=timeslice) log.info("Created gain table: %s" % (gaintable_summary(gt))) new_gt = GainTable(data=gt.data) assert new_gt.data.shape == gt.data.shape
def test_apply_gaintable_null(self): for spf, dpf in[('stokesI', 'stokesI'), ('stokesIQUV', 'linear'), ('stokesIQUV', 'circular')]: self.actualSetup(spf, dpf) gt = create_gaintable_from_blockvisibility(self.vis, timeslice='auto') gt.data['gain']*=0.0 original = copy_visibility(self.vis) vis = apply_gaintable(self.vis, gt, inverse=True, timeslice='auto') error = numpy.max(numpy.abs(vis.vis[:,0,1,...] - original.vis[:,0,1,...])) assert error < 1e-12, "Error = %s" % (error)
def test_create_gaintable_from_visibility(self): for spf, dpf in [('stokesIQUV', 'linear'), ('stokesIQUV', 'circular')]: self.actualSetup(spf, dpf) gt = create_gaintable_from_blockvisibility(self.vis) log.info("Created gain table: %s" % (gaintable_summary(gt))) gt = simulate_gaintable(gt, phase_error=0.1) original = copy_visibility(self.vis) vis = apply_gaintable(self.vis, gt) assert numpy.max(numpy.abs(vis.vis - original.vis)) > 0.0
def create_blockvisibility_iterator(config: Configuration, times: numpy.array, frequency: numpy.array, channel_bandwidth, phasecentre: SkyCoord, weight: float = 1, polarisation_frame=PolarisationFrame('stokesI'), integration_time=1.0, number_integrations=1, predict=predict_timeslice, model=None, components=None, phase_error=0.0, amplitude_error=0.0, sleep=0.0, **kwargs) -> BlockVisibility: """ Create a sequence of Visibilities and optionally predicting and coalescing This is useful mainly for performing large simulations. Do something like:: vis_iter = create_blockvisibility_iterator(config, times, frequency, channel_bandwidth, phasecentre=phasecentre, weight=1.0, integration_time=30.0, number_integrations=3) for i, vis in enumerate(vis_iter): if i == 0: fullvis = vis else: fullvis = append_visibility(fullvis, vis) :param config: Configuration of antennas :param times: hour angles in radians :param frequency: frequencies (Hz] Shape [nchan] :param weight: weight of a single sample :param phasecentre: phasecentre of observation :param npol: Number of polarizations :param integration_time: Integration time ('auto' or value in s) :param number_integrations: Number of integrations to be created at each time. :param model: Model image to be inserted :param components: Components to be inserted :param sleep_time: Time to sleep between yields :return: Visibility """ for time in times: actualtimes = time + numpy.arange(0, number_integrations) * integration_time * numpy.pi / 43200.0 bvis = create_blockvisibility(config, actualtimes, frequency=frequency, phasecentre=phasecentre, weight=weight, polarisation_frame=polarisation_frame, integration_time=integration_time, channel_bandwidth=channel_bandwidth) if model is not None: vis = predict(bvis, model, **kwargs) bvis = convert_visibility_to_blockvisibility(vis) if components is not None: bvis = predict_skycomponent_blockvisibility(bvis, components) # Add phase errors if phase_error > 0.0 or amplitude_error > 0.0: gt = create_gaintable_from_blockvisibility(bvis) gt = simulate_gaintable(gt=gt, phase_error=phase_error, amplitude_error=amplitude_error) vis = apply_gaintable(bvis, gt) import time time.sleep(sleep) yield bvis
def test_apply_gaintable_only(self): for spf, dpf in[('stokesI', 'stokesI'), ('stokesIQUV', 'linear'), ('stokesIQUV', 'circular')]: self.actualSetup(spf, dpf) gt = create_gaintable_from_blockvisibility(self.vis, timeslice='auto') log.info("Created gain table: %s" % (gaintable_summary(gt))) gt = simulate_gaintable(gt, phase_error=0.1, amplitude_error=0.01, timeslice='auto') original = copy_visibility(self.vis) vis = apply_gaintable(self.vis, gt, timeslice='auto') error = numpy.max(numpy.abs(vis.vis - original.vis)) assert error > 10.0, "Error = %f" % (error)
def solve_gaintable(vis: BlockVisibility, modelvis: BlockVisibility=None, phase_only=True, niter=30, tol=1e-8, crosspol=False, **kwargs) -> GainTable: """Solve a gain table by fitting an observed visibility to a model visibility If modelvis is None, a point source model is assumed. :param vis: BlockVisibility containing the observed data :param modelvis: BlockVisibility containing the visibility predicted by a model :param phase_only: Solve only for the phases (default=True) :param niter: Number of iterations (default 30) :param tol: Iteration stops when the fractional change in the gain solution is below this tolerance :param crosspol: Do solutions including cross polarisations i.e. XY, YX or RL, LR :return: GainTable containing solution """ assert type(vis) is BlockVisibility, "vis is not a BlockVisibility: %r" % vis assert type(modelvis) is BlockVisibility or type(modelvis) is None, "modelvis is not None or a " \ "BlockVisibility: %r" % vis if phase_only: log.info('solve_gaintable: Solving for phase only') else: log.info('solve_gaintable: Solving for complex gain') # 根据blockvisibility的元数据初始化一个gaintable gt = create_gaintable_from_blockvisibility(vis) for chunk, rows in enumerate(vis_timeslice_iter(vis, **kwargs)): # 对visibility按照time切片 # 切片好的visibility shape: [1,nant,nant,nchan,npol] subvis = create_visibility_from_rows(vis, rows) #若存在model if modelvis is not None: # model_visibility也要以相同的方式按time切片 model_subvis = create_visibility_from_rows(modelvis, rows) # 两个vis相除计算得到新的block_vis,其中的元数据未改变,只有vis和weight发生了改变 pointvis = divide_visibility(subvis, model_subvis) # 此处因为第0个axis是time轴,并且vis已经按照time分片,所以按照第0axis做了average以后值不发生变化 x = numpy.average(pointvis.vis, axis=0) xwt = numpy.average(pointvis.weight, axis=0) else: x = numpy.average(subvis.vis, axis=0) xwt = numpy.average(subvis.weight, axis=0) # 将数据填入gaintable中 # solve 和 timeslot的分界线 gt = solve_from_X(gt, x, xwt, chunk, crosspol, niter, phase_only, tol, npol=vis.polarisation_frame.npol) assert type(gt) is GainTable, "gt is not a GainTable: %r" % gt assert_vis_gt_compatible(vis, gt) return gt
def test_apply_gaintable_and_inverse_both(self): for spf, dpf in [('stokesIQUV', 'linear'), ('stokesIQUV', 'circular')]: self.actualSetup(spf, dpf) gt = create_gaintable_from_blockvisibility(self.vis) log.info("Created gain table: %s" % (gaintable_summary(gt))) gt = simulate_gaintable(gt, phase_error=0.1, amplitude_error=0.1) original = copy_visibility(self.vis) vis = apply_gaintable(self.vis, gt) vis = apply_gaintable(self.vis, gt, inverse=True) error = numpy.max(numpy.abs(vis.vis - original.vis)) assert error < 1e-12, "Error = %s" % (error)
def create_sagecal_thetas(vis: BlockVisibility, comps, **kwargs): """Create the thetas Create the data model for each window, from the visibility and the existing components :param comps: :param gt: :return: """ gt = create_gaintable_from_blockvisibility(vis, **kwargs) return [(copy_skycomponent(sc), copy_gaintable(gt)) for sc in comps]
def test_solve_gaintable_scalar(self): self.actualSetup('stokesI', 'stokesI', f=[100.0]) gt = create_gaintable_from_blockvisibility(self.vis) log.info("Created gain table: %s" % (gaintable_summary(gt))) gt = simulate_gaintable(gt, phase_error=10.0, amplitude_error=0.0) original = copy_visibility(self.vis) self.vis = apply_gaintable(self.vis, gt) gtsol = solve_gaintable(self.vis, original, phase_only=True, niter=200) residual = numpy.max(gtsol.residual) assert residual < 3e-8, "Max residual = %s" % (residual) assert numpy.max(numpy.abs(gtsol.gain - 1.0)) > 0.1
def test_create_gaintable_from_visibility_interval(self): for timeslice in [10.0, 'auto', 1e5]: for spf, dpf in[('stokesIQUV', 'linear')]: self.actualSetup(spf, dpf) gt = create_gaintable_from_blockvisibility(self.vis, timeslice=timeslice) log.info("Created gain table: %s" % (gaintable_summary(gt))) gt = simulate_gaintable(gt, phase_error=1.0, timeslice=timeslice) original = copy_visibility(self.vis) vis = apply_gaintable(self.vis, gt, timeslice=timeslice) assert numpy.max(numpy.abs(original.vis)) > 0.0 assert numpy.max(numpy.abs(vis.vis)) > 0.0 assert numpy.max(numpy.abs(vis.vis - original.vis)) > 0.0
def initialise_skymodel_cal_skymodel(vis: BlockVisibility, skymodels, **kwargs): """Create the skymodel Create the data model for each window, from the visibility and the existing components. Note that the components can be lists :param vis: BlockVisibility to process :param skymodels: List of skyModels :param kwargs: :return: """ gt = create_gaintable_from_blockvisibility(vis, **kwargs) return [(copy_skymodel(sm), copy_gaintable(gt)) for sm in skymodels]
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 ingest_visibility(self, freq=1e8, chan_width=1e6, times=None, reffrequency=None, add_errors=False): if times is None: times = [0.0] if reffrequency is None: reffrequency = [1e8] lowcore = create_named_configuration('LOWBD2-CORE') frequency = numpy.array([freq]) channel_bandwidth = numpy.array([chan_width]) # phasecentre = SkyCoord(ra=+180.0 * u.deg, dec=-60.0 * u.deg, frame='icrs', equinox='J2000') # Observe at zenith to ensure that timeslicing works well. We test that elsewhere. phasecentre = SkyCoord(ra=+180.0 * u.deg, dec=-60.0 * u.deg, frame='icrs', equinox='J2000') vt = create_blockvisibility(lowcore, times, frequency, channel_bandwidth=channel_bandwidth, weight=1.0, phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI")) cellsize = 0.001 model = create_image_from_visibility(vt, npixel=self.npixel, cellsize=cellsize, npol=1, frequency=reffrequency, polarisation_frame=PolarisationFrame("stokesI")) flux = numpy.array([[100.0]]) facets = 4 rpix = model.wcs.wcs.crpix - 1.0 spacing_pixels = self.npixel // facets centers = [-1.5, -0.5, 0.5, 1.5] comps = list() for iy in centers: for ix in centers: p = int(round(rpix[0] + ix * spacing_pixels * numpy.sign(model.wcs.wcs.cdelt[0]))), \ int(round(rpix[1] + iy * spacing_pixels * numpy.sign(model.wcs.wcs.cdelt[1]))) sc = pixel_to_skycoord(p[0], p[1], model.wcs, origin=1) comps.append(create_skycomponent(flux=flux, frequency=vt.frequency, direction=sc, polarisation_frame=PolarisationFrame("stokesI"))) predict_skycomponent_blockvisibility(vt, comps) insert_skycomponent(model, comps) self.actualmodel = copy_image(model) export_image_to_fits(model, '%s/test_imaging_model.fits' % (self.results_dir)) if add_errors: # These will be the same for all calls numpy.random.seed(180555) gt = create_gaintable_from_blockvisibility(vt) gt = simulate_gaintable(gt, phase_error=1.0, amplitude_error=0.0) vt = apply_gaintable(vt, gt) return vt
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 corrupt_vis(vis, gt, **kwargs): if gt is None: gt = create_gaintable_from_blockvisibility(vis, **kwargs) gt = simulate_gaintable(gt, **kwargs) return apply_gaintable(vis, gt)
predicted_vis = predict_function(block_vis, gleam_model, vis_slices=51, context='wstack') #print("np.sum(predicted_vis.data): ", numpy.sum(predicted_vis.data['vis'])) block_vis=convert_visibility_to_blockvisibility(predicted_vis) #print("np.sum(block_vis.data): ", numpy.sum(block_vis.data['vis'])) #print("nchan npol nants ", block_vis.nchan, block_vis.npol, block_vis.nants) #print("uvw", block_vis.uvw, numpy.sum(block_vis.uvw)) #print("vis", block_vis.vis, numpy.sum(block_vis.vis)) #print("weight", block_vis.weight, numpy.sum(block_vis.weight)) #print("time", block_vis.time, numpy.sum(block_vis.time)) #print("integration_time", block_vis.integration_time, numpy.sum(block_vis.integration_time)) #print("nvis, size", block_vis.nvis, block_vis.size()) gt = create_gaintable_from_blockvisibility(block_vis) #print("np.sum(gt.data): ", numpy.sum(gt.data['gain'])) 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))
def create_calskymodel(vis, skymodel): gt = create_gaintable_from_blockvisibility(vis, **kwargs) return (copy_skymodel(skymodel), copy_gaintable(gt))
def solve_gaintable(vis: BlockVisibility, modelvis: BlockVisibility, phase_only=True, niter=30, tol=1e-8, crosspol=False, **kwargs) -> GainTable: """Solve a gain table to a block visibility :param vis: BlockVisibility containing the observed data :param modelvis: BlockVisibility containing the visibility predicted by a model :param phase_only: Solve only for the phases (default=True) :param niter: Number of iterations (default 30) :param tol: Iteration stops when the fractional change in the gain solution is below this tolerance :param crosspol: Do solutions including cross polarisations i.e. XY, YX or RL, LR :returns: GainTable containing solution """ assert type( vis) is BlockVisibility, "vis is not a BlockVisibility: %r" % vis assert type( modelvis ) is BlockVisibility, "modelvis is not a BlockVisibility: %r" % vis if phase_only: log.info('solve_gaintable: Solving for phase only') else: log.info('solve_gaintable: Solving for complex gain') gt = create_gaintable_from_blockvisibility(vis) for chunk, rows in enumerate(vis_timeslice_iter(vis)): x, xwt = remove_model(vis.vis[rows], vis.weight[rows], modelvis.vis[rows], isscalar=vis.polarisation_frame.npol == 1, crosspol=crosspol) # Now average over time, chan. The axes of x are time, antenna2, antenna1, chan, pol xave = numpy.average(x, axis=0) xwtAve = numpy.average(xwt, axis=0) mask = xwtAve <= 0.0 xave[mask] = 0.0 gainshape = gt.data['gain'][chunk, ...].shape if vis.polarisation_frame.npol > 1: if crosspol: gt.data['gain'][chunk, ...], gt.data['weight'][chunk, ...], gt.data['residual'][chunk, ...] = \ solve_antenna_gains_itsubs_matrix(gainshape, xave, xwtAve, phase_only=phase_only, niter=niter, tol=tol) else: gt.data['gain'][chunk, ...], gt.data['weight'][chunk, ...], gt.data['residual'][chunk, ...] = \ solve_antenna_gains_itsubs_vector(gainshape, xave, xwtAve, phase_only=phase_only, niter=niter, tol=tol) else: gt.data['gain'][chunk, ...], gt.data['weight'][chunk, ...], gt.data['residual'][chunk, ...] = \ solve_antenna_gains_itsubs_scalar(gainshape, xave, xwtAve, phase_only=phase_only, niter=niter, tol=tol) assert type(gt) is GainTable, "gt is not a GainTable: %r" % gt return gt
def test_peel_skycomponent_blockvisibility(self): df = 1e6 frequency = numpy.array([1e8 - df, 1e8, 1e8 + df]) channel_bandwidth = numpy.array([df, df, df]) # Define the component and give it some spectral behaviour f = numpy.array([100.0, 20.0, -10.0, 1.0]) flux = numpy.array([f, 0.8 * f, 0.6 * f]) phasecentre = SkyCoord(0 * u.deg, -60.0 * u.deg) config = create_named_configuration('LOWBD2-CORE') peeldirection = SkyCoord(+15 * u.deg, -60.0 * u.deg) times = numpy.linspace(-3.0, 3.0, 7) * numpy.pi / 12.0 # Make the visibility vis = create_blockvisibility( config, times, frequency, phasecentre=phasecentre, weight=1.0, polarisation_frame=PolarisationFrame('linear'), channel_bandwidth=channel_bandwidth) vis.data['vis'][...] = 0.0 # First add in the source to be peeled. peel = Skycomponent(direction=peeldirection, frequency=frequency, flux=flux, polarisation_frame=PolarisationFrame("stokesIQUV")) vis = predict_skycomponent_visibility(vis, peel) # Make a gaintable and apply it to the visibility of the peeling source gt = create_gaintable_from_blockvisibility(vis, timeslice='auto') gt = simulate_gaintable(gt, phase_error=0.01, amplitude_error=0.01, timeslice='auto') gt.data['gain'] *= 0.3 vis = apply_gaintable(vis, gt, timeslice='auto') # Now create a plausible field using the GLEAM sources model = create_image_from_visibility( vis, cellsize=0.001, frequency=frequency, polarisation_frame=PolarisationFrame('stokesIQUV')) bm = create_low_test_beam(model=model) sc = create_low_test_skycomponents_from_gleam( flux_limit=1.0, polarisation_frame=PolarisationFrame("stokesIQUV"), frequency=frequency, kind='cubic', phasecentre=phasecentre, radius=0.1) sc = apply_beam_to_skycomponent(sc, bm) # Add in the visibility due to these sources vis = predict_skycomponent_visibility(vis, sc) assert numpy.max(numpy.abs(vis.vis)) > 0.0 # Now we can peel vis, peel_gts = peel_skycomponent_blockvisibility(vis, peel) assert len(peel_gts) == 1 residual = numpy.max(peel_gts[0].residual) assert residual < 0.7, "Peak residual %.6f too large" % (residual) im, sumwt = invert_timeslice(vis, model, timeslice='auto') qa = qa_image(im) assert numpy.abs(qa.data['max'] - 14.2) < 1.0, str(qa)