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 sagecal_fit_gaintable(evis, theta, gain=0.1, niter=3, tol=1e-3, **kwargs): """Fit a gaintable to a visibility i.e. A13 This is the update to the gain part of the window :param evis: :param theta: :param kwargs: :return: """ previous_gt = copy_gaintable(theta[1]) gt = copy_gaintable(theta[1]) model_vis = copy_visibility(evis, zero=True) model_vis = predict_skycomponent_visibility(model_vis, theta[0]) gt = solve_gaintable(evis, model_vis, gt=gt, niter=niter, phase_only=True, gain=0.5, tol=1e-4, **kwargs) gt.data['gain'][...] = gain * gt.data['gain'][...] + \ (1 - gain) * previous_gt.data['gain'][...] gt.data['gain'][...] /= numpy.abs(previous_gt.data['gain'][...]) return gt
def peel_skycomponent_blockvisibility(vis: BlockVisibility, sc: Union[Skycomponent, List[Skycomponent]], remove=True)\ -> (BlockVisibility, List[GainTable]): """ Peel a collection of components. Sequentially solve the gain towards each Skycomponent and optionally remove the corrupted visibility from the observed visibility. :param params: :param vis: Visibility to be processed :param sc: Skycomponent or list of Skycomponents :return: subtracted visibility and list of GainTables """ assert isinstance( vis, BlockVisibility), "vis is not a BlockVisibility: %r" % vis if not isinstance(sc, collections.Iterable): sc = [sc] gtlist = [] for comp in sc: assert comp.shape == 'Point', "Cannot handle shape %s" % comp.shape modelvis = copy_visibility(vis, zero=True) modelvis = predict_skycomponent_blockvisibility(modelvis, comp) gt = solve_gaintable(vis, modelvis, phase_only=False) modelvis = apply_gaintable(modelvis, gt) if remove: vis.data['vis'] -= modelvis.data['vis'] gtlist.append(gt) return vis, gtlist
def calibrate_blockvisibility(bvt: BlockVisibility, model: Image = None, components=None, predict=predict_2d, **kwargs) -> BlockVisibility: """ calibrate BlockVisibility with respect to model and optionally components :param bvt: BlockVisibility :param model: Model image :param components: Sky components :return: 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, inverse=get_parameter(kwargs, "inverse", False))
def calibrate_visibility(vt: Visibility, model=None, components=None, predict=predict_2d, **kwargs): """ calibrate Visibility with respect to model and optionally components :param vt: Visibility :param model: Model image :param components: Sky components :returns: 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, **kwargs) return convert_blockvisibility_to_visibility(bvt)[0]
def selfcal_single(vis, model, **kwargs): if vis is not None: predicted = copy_visibility(vis) predicted = predict(predicted, model, **kwargs) gtsol = solve_gaintable(vis, predicted, **kwargs) vis = apply_gaintable(vis, gtsol, inverse=True, **kwargs) return vis else: return None
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) 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)
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_solve_gaintable_scalar_bandpass(self): self.actualSetup('stokesI', 'stokesI', f=[100.0], vnchan=128) 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.01, smooth_channels=8) original = copy_visibility(self.vis) self.vis = apply_gaintable(self.vis, gt) gtsol = solve_gaintable(self.vis, original, phase_only=False, 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 create_calibrate_graph_list(vis_graph_list, model_vis_graph_list, global_solution=True, **kwargs): if global_solution: point_vis_graph_list = divide_handle(vis_graph_list, model_vis_graph_list, **kwargs) point_vis_graph_list = [ tup[1] for tup in point_vis_graph_list.collect() ] global_point_vis_graph = visibility_gather_channel( point_vis_graph_list) global_point_vis_graph = integrate_visibility_by_channel( global_point_vis_graph) gt_graph = solve_gaintable(global_point_vis_graph, **kwargs) return apply_gain_handle(vis_graph_list, gt_graph) else: return solve_and_apply_handle(vis_graph_list, model_vis_graph_list, **kwargs)
def skymodel_cal_fit_gaintable(evis, calskymodel, gain=0.1, niter=3, tol=1e-3, **kwargs): """Fit a gaintable to a visibility This is the update to the gain part of the window :param evis: Expected vis for this ssm :param calskymodel: csm element being fit :param gain: Gain in step :param niter: Number of iterations :param kwargs: Gaintable """ previous_gt = copy_gaintable(calskymodel[1]) gt = copy_gaintable(calskymodel[1]) model_vis = copy_visibility(evis, zero=True) model_vis = predict_skycomponent_visibility(model_vis, calskymodel[0].components) gt = solve_gaintable(evis, model_vis, gt=gt, niter=niter, phase_only=True, gain=0.5, tol=1e-4, **kwargs) gt.data['gain'][...] = gain * gt.data['gain'][...] + \ (1 - gain) * previous_gt.data['gain'][...] gt.data['gain'][...] /= numpy.abs(previous_gt.data['gain'][...]) return gt
def rcal(vis: BlockVisibility, components, **kwargs) -> GainTable: """ Real-time calibration pipeline. Reads visibilities through a BlockVisibility iterator, calculates model visibilities according to a component-based sky model, and performs calibration solution, writing a gaintable for each chunk of visibilities. :param vis: Visibility or Union(Visibility, Iterable) :param components: Component-based sky model :param kwargs: Parameters :return: gaintable """ if not isinstance(vis, collections.Iterable): vis = [vis] for ichunk, vischunk in enumerate(vis): vispred = copy_visibility(vischunk, zero=True) vispred = predict_skycomponent_blockvisibility(vispred, components) gt = solve_gaintable(vischunk, vispred, **kwargs) yield gt
def solve_and_apply(vis, modelvis): gt = solve_gaintable(vis, modelvis, **kwargs) return apply_gaintable(vis, gt, **kwargs)
def calibrate_single(vis: BlockVisibility, vispred: BlockVisibility, **kwargs): return solve_gaintable(vis, vispred, **kwargs)
def test_solve_gaintable(self): ''' 测试solve_gaintable :return: ''' #===串行=== newphasecentre = SkyCoord(ra=+15.0 * u.deg, dec=-10.0 * u.deg, frame='icrs', equinox='J2000') image = copy.deepcopy(image_graph) image.data = np.zeros_like(image.data) #将lsm插入到image中 insert_skycomponent(image, comp, insert_method="Sinc") # 期间可能会有fft和reproject暂不考虑 #生成telescope_data telescope_data = copy.deepcopy(vis) #image做卷积并且degrid生成modelvis model_vis = predict_facets(telescope_data, image) model_vis = predict_skycomponent_visibility(model_vis, comp) model_vis = decoalesce_visibility(model_vis) #模拟望远镜实际接收到的visibility blockvis_observed = create_blockvisibility( lowcore, times=times, frequency=frequency, channel_bandwidth=channel_bandwidth, phasecentre=phasecentre, weight=1, polarisation_frame=PolarisationFrame('linear'), integration_time=1.0) # 用自然数值填充vis,模拟实际接收到的block_visibility,并且各个vis的值各不相同易于区分 blockvis_observed.data['vis'] = range(blockvis_observed.nvis) gt = solve_gaintable(blockvis_observed, model_vis) apply_gaintable(blockvis_observed, gt) #===并行=== # TODO暂未完成 # 生成telescope_data telescope_data, visibility_share = visibility_to_visibility_para( vis, 'npol') ims, image_share = image_to_image_para(image_graph, FACETS) ims2 = [] for i in ims: insert_skycomponent_para(i, comp, insert_method='Sinc') ims2.append(i) model_vis1 = [] viss2 = [] for v in viss: for im in ims2: if v[0][0] == im.frequency: temp = predict_facets_para(v[1], im) # (chan, time, ant1, ant2) model_vis1.append( ((v[0][0], v[0][1], v[0][2], v[0][3]), temp)) viss2.append(((v[0][0], v[0][1], v[0][2], v[0][3], im.facet, im.polarisation), phaserotate_visibility_para(temp, newphasecentre, tangent=False))) predict_skycoponent_visibility_para_modified(viss2, comp, mode='test2') # 将visibility的facet和polarisation合并起来 viss3 = defaultdict(list) model_vis2 = defaultdict(list) for v in range(0, len(viss2), 4 * 4): temp = copy.deepcopy(viss2[v][1]) temp2 = copy.deepcopy(model_vis1[v][1]) for id in range(v + 1, v + 16): temp.data['vis'] += viss2[id][1].data['vis'] temp2.data['vis'] += model_vis1[id][1].data['vis'] viss3[viss2[v][0][0:2]].append(((viss2[v][0][2:4]), temp)) model_vis2[model_vis1[v][0][0:2]].append( ((model_vis1[v][0][2:]), temp2)) # TODO 将并行程序从此开始填入 gts = [] for key in viss3: xs = [] xwts = [] for v, mv in zip(viss3[key], model_vis2[key]): x, xwt = solve_gaintable_para(v[1], mv[1]) xs.append(((0, 0, 0, 0, key[0], key[1], v[0][0], v[0][1]), x)) xwts.append(xwt) g = create_gaintable_from_visibility_para(viss3[key][0][1], 3) solve_from_X_para(xs, xwts, g, npol=viss3[key][0][1].npol) gts.append((key, g)) gaintable_right(gt, gts) new_gain = combine_gaintable(gt, gts) for key in viss3: print(key) chan, time = key temp = gaintable_for_para(new_gain.gain[time, :, chan, :, :].reshape[1, 3, 2, 2]) apply_gaintable_para(viss3[key], temp) for key in viss3: chan, time = key vis_serial = block_vis.vis[time, :, :chan, :] for id, v in viss3[key]: ant1 = id[2] ant2 = id[3] vis_serial = block_vis.vis[time, ant2, ant1, chan] print(vis_serial) print(v.vis) print()
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_and_apply_kernel(ixs, **kwargs): vis, model_vis = ixs gt = solve_gaintable(vis, model_vis, **kwargs) return apply_gaintable(vis, gt, inverse=True, **kwargs)