def copy_skymodel(sm): """ Copy a sky model """ if sm.components is not None: newcomps = [copy_skycomponent(comp) for comp in sm.components] else: newcomps = None if sm.image is not None: newimage = copy_image(sm.image) else: newimage = None if sm.mask is not None: newmask = copy_image(sm.mask) else: newmask = None if sm.gaintable is not None: newgt = copy_gaintable(sm.gaintable) else: newgt = None return SkyModel(components=newcomps, image=newimage, gaintable=newgt, mask=newmask, fixed=sm.fixed)
def solve_skymodel(vis, skymodel, gain=0.1, **kwargs): """Fit a single skymodel to a visibility :param evis: Expected vis for this ssm :param modelpartition: scm element being fit i.e. (skymodel, gaintable) tuple :param gain: Gain in step :param method: 'fit' or 'sum' :param kwargs: :return: skycomponent """ if skymodel.fixed: return skymodel new_comps = list() for comp in skymodel.components: new_comp = copy_skycomponent(comp) new_comp, _ = fit_visibility(vis, new_comp) new_comp.flux = gain * new_comp.flux + (1.0 - gain) * comp.flux new_comps.append(new_comp) new_images = list() for im in skymodel.images: new_image = copy_image(im) # new_image = solve_image_arlexecute_workflow(vis, new_image, **kwargs) new_images.append(new_image) return SkyModel(components=new_comps, images=new_images)
def show_components(im, comps, npixels=128, fig=None, vmax=None, vmin=None): """ Show components against an image :param im: :param comps: :param npixels: :param fig: :return: """ import matplotlib.pyplot as plt if vmax is None: vmax = numpy.max(im.data[0, 0, ...]) if vmin is None: vmin = numpy.min(im.data[0, 0, ...]) if not fig: fig = plt.figure() plt.clf() for isc, sc in enumerate(comps): newim = copy_image(im) plt.subplot(111, projection=newim.wcs.sub([1, 2])) centre = numpy.round(skycoord_to_pixel(sc.direction, newim.wcs, 1, 'wcs')).astype('int') newim.data = newim.data[:, :, (centre[1] - npixels // 2):(centre[1] + npixels // 2), (centre[0] - npixels // 2):(centre[0] + npixels // 2)] newim.wcs.wcs.crpix[0] -= centre[0] - npixels // 2 newim.wcs.wcs.crpix[1] -= centre[1] - npixels // 2 plt.imshow(newim.data[0, 0, ...], origin='lower', cmap='Greys', vmax=vmax, vmin=vmin) x, y = skycoord_to_pixel(sc.direction, newim.wcs, 0, 'wcs') plt.plot(x, y, marker='+', color='red') plt.title('Name = %s, flux = %s' % (sc.name, sc.flux)) plt.show()
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 deconvolve(dirty, psf, model, facet, gthreshold, msk=None): if prefix == '': lprefix = "facet %d" % facet else: lprefix = "%s, facet %d" % (prefix, facet) if nmoment > 0: moment0 = calculate_image_frequency_moments(dirty) this_peak = numpy.max(numpy.abs( moment0.data[0, ...])) / dirty.data.shape[0] else: ref_chan = dirty.data.shape[0] // 2 this_peak = numpy.max(numpy.abs(dirty.data[ref_chan, ...])) if this_peak > 1.1 * gthreshold: kwargs['threshold'] = gthreshold result, _ = deconvolve_cube(dirty, psf, prefix=lprefix, mask=msk, **kwargs) if result.data.shape[0] == model.data.shape[0]: result.data += model.data return result else: return copy_image(model)
def restore_cube(model: Image, psf: Image, residual=None, **kwargs) -> Image: """ Restore the model image to the residuals :params psf: Input PSF :return: restored image """ assert isinstance(model, Image), model assert isinstance(psf, Image), psf assert residual is None or isinstance(residual, Image), residual restored = copy_image(model) npixel = psf.data.shape[3] sl = slice(npixel // 2 - 7, npixel // 2 + 8) size = get_parameter(kwargs, "psfwidth", None) if size is None: # isotropic at the moment! from scipy.optimize import minpack try: fit = fit_2dgaussian(psf.data[0, 0, sl, sl]) if fit.x_stddev <= 0.0 or fit.y_stddev <= 0.0: log.debug( 'restore_cube: error in fitting to psf, using 1 pixel stddev' ) size = 1.0 else: size = max(fit.x_stddev, fit.y_stddev) log.debug('restore_cube: psfwidth = %s' % (size)) except minpack.error as err: log.debug('restore_cube: minpack error, using 1 pixel stddev') size = 1.0 except ValueError as err: log.debug( 'restore_cube: warning in fit to psf, using 1 pixel stddev') size = 1.0 else: log.debug('restore_cube: Using specified psfwidth = %s' % (size)) # TODO: Remove filter when astropy fixes convolve import warnings warnings.simplefilter(action='ignore', category=FutureWarning) from astropy.convolution import Gaussian2DKernel, convolve_fft # By convention, we normalise the peak not the integral so this is the volume of the Gaussian norm = 2.0 * numpy.pi * size**2 gk = Gaussian2DKernel(size) for chan in range(model.shape[0]): for pol in range(model.shape[1]): restored.data[chan, pol, :, :] = norm * convolve_fft( model.data[chan, pol, :, :], gk, normalize_kernel=False, allow_huge=True) if residual is not None: restored.data += residual.data return restored
def copy_skymodel(sm): """ Copy a sky model """ return SkyModel( components=[copy_skycomponent(comp) for comp in sm.components], images=[copy_image(im) for im in sm.images], fixed=sm.fixed)
def partition_skymodel_by_flux(sc, model, flux_threshold=-numpy.inf): """Partition skymodel according to flux :param sc: :param model: :param flux_threshold: :return: """ brightsc = filter_skycomponents_by_flux(sc, flux_min=flux_threshold) weaksc = filter_skycomponents_by_flux(sc, flux_max=flux_threshold) log.info('Converted %d components into %d bright components and one image containing %d components' % (len(sc), len(brightsc), len(weaksc))) im = copy_image(model) im = insert_skycomponent(im, weaksc) return SkyModel(components=[copy_skycomponent(comp) for comp in brightsc], image=copy_image(im), mask=None, fixed=False)
def expand_skymodel_by_skycomponents(sm, **kwargs): """ Expand a sky model so that all components and the image are in separate skymodels The mask and gaintable are taken to apply for all new skymodels. :param sm: SkyModel :return: List of SkyModels """ result = [SkyModel(components=[comp], image=None, gaintable=copy_gaintable(sm.gaintable), mask=copy_image(sm.mask), fixed=sm.fixed) for comp in sm.components] if sm.image is not None: result.append(SkyModel(components=None, image=copy_image(sm.image), gaintable=copy_gaintable(sm.gaintable), mask=copy_image(sm.mask), fixed=sm.fixed)) return result
def calculate_image_from_frequency_moments(im: Image, moment_image: Image, reference_frequency=None) -> Image: """Calculate image from frequency weighted moments Weights are ((freq-reference_frequency)/reference_frequency)**moment Note that a new image is created For example, to find the moments and then reconstruct from just the moments:: moment_cube = calculate_image_frequency_moments(model_multichannel, nmoments=5) reconstructed_cube = calculate_image_from_frequency_moments(model_multichannel, moment_cube) :param im: Image cube to be reconstructed :param moment_image: Moment cube (constructed using calculate_image_frequency_moments) :param reference_frequency: Reference frequency (default None uses average) :return: reconstructed image """ assert isinstance(im, Image) nchan, npol, ny, nx = im.shape nmoments, mnpol, mny, mnx = moment_image.shape assert npol == mnpol assert ny == mny assert nx == mnx assert moment_image.wcs.wcs.ctype[ 3] == 'MOMENT', "Second image should be a moment image" channels = numpy.arange(nchan) with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) freq = im.wcs.sub(['spectral']).wcs_pix2world(channels, 0)[0] if reference_frequency is None: reference_frequency = numpy.average(freq) log.debug( "calculate_image_from_frequency_moments: Reference frequency = %.3f (MHz)" % (reference_frequency)) newim = copy_image(im) newim.data[...] = 0.0 for moment in range(nmoments): for chan in range(nchan): weight = numpy.power( (freq[chan] - reference_frequency) / reference_frequency, moment) newim.data[chan, ...] += moment_image.data[moment, ...] * weight return newim
def update_skymodel_from_image(sm, im, damping=0.5): """Update a skymodel for an image :param sm: :param im: :return: """ for i, th in enumerate(sm): newim = copy_image(im) if th.mask is not None: newim.data *= th.mask.data th.image.data += damping * newim.data return sm
def calculate_skymodel_equivalent_image(sm): """Calculate an equivalent image for a skymodel :param sm: :return: """ combined_model = copy_image(sm[0].image) combined_model.data[...] = 0.0 for th in sm: if th.image is not None: if th.mask is not None: combined_model.data += th.mask.data * th.image.data else: combined_model.data += th.image.data return combined_model
def ft_ift_sm(ov, sm, g): assert isinstance(ov, Visibility) or isinstance(ov, BlockVisibility), ov 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] 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=[g], **kwargs)[0] assert isinstance(sm.image, Image), sm.image 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 deconvolve(dirty, psf, model, facet, gthreshold): import time starttime = time.time() if prefix == '': lprefix = "facet %d" % facet else: lprefix = "%s, facet %d" % (prefix, facet) nmoments = get_parameter(kwargs, "nmoments", 0) if nmoments > 0: moment0 = calculate_image_frequency_moments(dirty) this_peak = numpy.max(numpy.abs( moment0.data[0, ...])) / dirty.data.shape[0] else: this_peak = numpy.max(numpy.abs(dirty.data[0, ...])) if this_peak > 1.1 * gthreshold: log.info( "deconvolve_list_serial_workflow %s: cleaning - peak %.6f > 1.1 * threshold %.6f" % (lprefix, this_peak, gthreshold)) kwargs['threshold'] = gthreshold result, _ = deconvolve_cube(dirty, psf, prefix=lprefix, **kwargs) if result.data.shape[0] == model.data.shape[0]: result.data += model.data else: log.warning( "deconvolve_list_serial_workflow %s: Initial model %s and clean result %s do not have the same shape" % (lprefix, str( model.data.shape[0]), str(result.data.shape[0]))) flux = numpy.sum(result.data[0, 0, ...]) log.info( '### %s, %.6f, %.6f, True, %.3f # cycle, facet, peak, cleaned flux, clean, time?' % (lprefix, this_peak, flux, time.time() - starttime)) return result else: log.info( "deconvolve_list_serial_workflow %s: Not cleaning - peak %.6f <= 1.1 * threshold %.6f" % (lprefix, this_peak, gthreshold)) log.info( '### %s, %.6f, %.6f, False, %.3f # cycle, facet, peak, cleaned flux, clean, time?' % (lprefix, this_peak, 0.0, time.time() - starttime)) return copy_image(model)
def deconvolve(dirty, psf, model, facet, gthreshold): if prefix == '': lprefix = "facet %d" % facet else: lprefix = "%s, facet %d" % (prefix, facet) if nmoments > 0: moment0 = calculate_image_frequency_moments(dirty) this_peak = numpy.max(numpy.abs( moment0.data[0, ...])) / dirty.data.shape[0] else: this_peak = numpy.max(numpy.abs(dirty.data[0, ...])) if this_peak > 1.1 * gthreshold: # log.info( # "deconvolve_list_arlexecute_workflow %s: cleaning - peak %.6f > 1.1 * threshold %.6f" % ( # lprefix, this_peak, # gthreshold)) kwargs['threshold'] = gthreshold result, _ = deconvolve_cube(dirty, psf, prefix=lprefix, **kwargs) if result.data.shape[0] == model.data.shape[0]: result.data += model.data # else: # log.warning( # "deconvolve_list_arlexecute_workflow %s: Initial model %s and clean result %s do not have the same shape" % # (lprefix, str(model.data.shape[0]), str(result.data.shape[0]))) # flux = numpy.sum(result.data[0, 0, ...]) # log.info('### %s, %.6f, %.6f, True, # cycle, facet, peak, cleaned flux, clean' # % (lprefix, this_peak, flux[0])) # return result else: # log.info("deconvolve_list_arlexecute_workflow %s: Not cleaning - peak %.6f <= 1.1 * threshold %.6f" % ( # lprefix, this_peak, # gthreshold)) # log.info('### %s, %.6f, %.6f, False, %.3f # cycle, facet, peak, cleaned flux, clean' # % (lprefix, this_peak, 0.0)) return copy_image(model)
def initialize_skymodel_voronoi(model, comps, gt=None): """Create a skymodel by Voronoi partitioning of the components, fill with components :param model: Model image :param comps: Skycomponents :param gt: Gaintable :return: """ skymodel_images = list() for i, mask in enumerate(image_voronoi_iter(model, comps)): im = copy_image(model) im.data *= mask.data if gt is not None: newgt = copy_gaintable(gt) newgt.phasecentre = comps[i].direction else: newgt=None skymodel_images.append(SkyModel(image=im, components=None, gaintable=newgt, mask=mask)) return skymodel_images
def ft_ift_sm(ov, sm): assert isinstance(ov, Visibility), ov 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] assert isinstance(sm.image, Image), sm.image 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 show_skymodel(sms, psf_width=1.75, cm='Greys', vmax=None, vmin=None): sp = 1 for ism, sm in enumerate(sms): plt.clf() plt.subplot(121, projection=sms[ism].image.wcs.sub([1, 2])) sp += 1 smodel = copy_image(sms[ism].image) smodel = insert_skycomponent(smodel, sms[ism].components) smodel = smooth_image(smodel, psf_width) if vmax is None: vmax = numpy.max(smodel.data[0, 0, ...]) if vmin is None: vmin = numpy.min(smodel.data[0, 0, ...]) plt.imshow(smodel.data[0, 0, ...], origin='lower', cmap=cm, vmax=vmax, vmin=vmin) plt.xlabel(sms[ism].image.wcs.wcs.ctype[0]) plt.ylabel(sms[ism].image.wcs.wcs.ctype[1]) plt.title('SkyModel%d' % ism) components = sms[ism].components if components is not None: for sc in components: x, y = skycoord_to_pixel(sc.direction, sms[ism].image.wcs, 0, 'wcs') plt.plot(x, y, marker='+', color='red') gaintable = sms[ism].gaintable if gaintable is not None: plt.subplot(122) sp += 1 phase = numpy.angle(sm.gaintable.gain[:, :, 0, 0, 0]) phase -= phase[:, 0][:, numpy.newaxis] plt.imshow(phase, origin='lower') plt.xlabel('Dish/Station') plt.ylabel('Integration') plt.show()
marker='.', label='Original') plt.semilogy(numpy.arange(len(ical_fluxes)), ical_fluxes, marker='.', label='ICAL') plt.semilogy(numpy.arange(len(mpccal_fluxes)), mpccal_fluxes, marker='.', label='MPCCAL') plt.title('All component fluxes') plt.ylabel('Flux (Jy)') plt.legend() plt.show(block=block_plots) difference_image = copy_image(mpccal_restored) difference_image.data -= ical_restored.data print(qa_image(difference_image, context='MPCCAL - ICAL image')) show_image(difference_image, title='MPCCAL - ICAL image', components=ical_components) plt.show(block=block_plots) export_image_to_fits( difference_image, arl_path( 'test_results/low-sims-mpc-mpccal-ical-restored_%.1frmax.fits' % rmax)) newscreen = create_empty_image_like(screen) gaintables = [sm.gaintable for sm in mpccal_skymodel]
def create_awterm_convolutionfunction(im, make_pb=None, nw=1, wstep=1e15, oversampling=8, support=6, use_aaf=True, maxsupport=512): """ Fill AW projection kernel into a GridData. :param im: Image template :param make_pb: Function to make the primary beam model image :param nw: Number of w planes :param wstep: Step in w (wavelengths) :param oversampling: Oversampling of the convolution function in uv space :return: griddata correction Image, griddata kernel as GridData """ d2r = numpy.pi / 180.0 # We only need the griddata correction function for the PSWF so we make # it for the shape of the image nchan, npol, ony, onx = im.data.shape assert isinstance(im, Image) # Calculate the template convolution kernel. cf = create_convolutionfunction_from_image(im, oversampling=oversampling, support=support) cf_shape = list(cf.data.shape) cf_shape[2] = nw cf.data = numpy.zeros(cf_shape).astype('complex') cf.grid_wcs.wcs.crpix[4] = nw // 2 + 1.0 cf.grid_wcs.wcs.cdelt[4] = wstep cf.grid_wcs.wcs.ctype[4] = 'WW' if numpy.abs(wstep) > 0.0: w_list = cf.grid_wcs.sub([5]).wcs_pix2world(range(nw), 0)[0] else: w_list = [0.0] assert isinstance(oversampling, int) assert oversampling > 0 nx = max(maxsupport, 2 * oversampling * support) ny = max(maxsupport, 2 * oversampling * support) qnx = nx // oversampling qny = ny // oversampling cf.data[...] = 0.0 subim = copy_image(im) ccell = onx * numpy.abs(d2r * subim.wcs.wcs.cdelt[0]) / qnx subim.data = numpy.zeros([nchan, npol, qny, qnx]) subim.wcs.wcs.cdelt[0] = -ccell / d2r subim.wcs.wcs.cdelt[1] = +ccell / d2r subim.wcs.wcs.crpix[0] = qnx // 2 + 1.0 subim.wcs.wcs.crpix[1] = qny // 2 + 1.0 if use_aaf: this_pswf_gcf, _ = create_pswf_convolutionfunction(subim, oversampling=1, support=6) norm = 1.0 / this_pswf_gcf.data else: norm = 1.0 if make_pb is not None: pb = make_pb(subim) rpb, footprint = reproject_image(pb, subim.wcs, shape=subim.shape) rpb.data[footprint.data < 1e-6] = 0.0 norm *= rpb.data # We might need to work with a larger image padded_shape = [nchan, npol, ny, nx] thisplane = copy_image(subim) thisplane.data = numpy.zeros(thisplane.shape, dtype='complex') for z, w in enumerate(w_list): thisplane.data[...] = 0.0 + 0.0j thisplane = create_w_term_like(thisplane, w, dopol=True) thisplane.data *= norm paddedplane = pad_image(thisplane, padded_shape) paddedplane = fft_image(paddedplane) ycen, xcen = ny // 2, nx // 2 for y in range(oversampling): ybeg = y + ycen + (support * oversampling) // 2 - oversampling // 2 yend = y + ycen - (support * oversampling) // 2 - oversampling // 2 vv = range(ybeg, yend, -oversampling) for x in range(oversampling): xbeg = x + xcen + (support * oversampling) // 2 - oversampling // 2 xend = x + xcen - (support * oversampling) // 2 - oversampling // 2 uu = range(xbeg, xend, -oversampling) for chan in range(nchan): for pol in range(npol): cf.data[chan, pol, z, y, x, :, :] = paddedplane.data[ chan, pol, :, :][vv, :][:, uu] cf.data /= numpy.sum( numpy.real(cf.data[0, 0, nw // 2, oversampling // 2, oversampling // 2, :, :])) cf.data = numpy.conjugate(cf.data) if use_aaf: pswf_gcf, _ = create_pswf_convolutionfunction(im, oversampling=1, support=6) else: pswf_gcf = create_empty_image_like(im) pswf_gcf.data[...] = 1.0 return pswf_gcf, cf
def create_awterm_convolutionfunction(im, make_pb=None, nw=1, wstep=1e15, oversampling=8, support=6, use_aaf=True, maxsupport=512, **kwargs): """ Fill AW projection kernel into a GridData. :param im: Image template :param make_pb: Function to make the primary beam model image (hint: use a partial) :param nw: Number of w planes :param wstep: Step in w (wavelengths) :param oversampling: Oversampling of the convolution function in uv space :return: griddata correction Image, griddata kernel as GridData """ d2r = numpy.pi / 180.0 # We only need the griddata correction function for the PSWF so we make # it for the shape of the image nchan, npol, ony, onx = im.data.shape assert isinstance(im, Image) # Calculate the template convolution kernel. cf = create_convolutionfunction_from_image(im, oversampling=oversampling, support=support) cf_shape = list(cf.data.shape) cf_shape[2] = nw cf.data = numpy.zeros(cf_shape).astype('complex') cf.grid_wcs.wcs.crpix[4] = nw // 2 + 1.0 cf.grid_wcs.wcs.cdelt[4] = wstep cf.grid_wcs.wcs.ctype[4] = 'WW' if numpy.abs(wstep) > 0.0: w_list = cf.grid_wcs.sub([5]).wcs_pix2world(range(nw), 0)[0] else: w_list = [0.0] assert isinstance(oversampling, int) assert oversampling > 0 nx = max(maxsupport, 2 * oversampling * support) ny = max(maxsupport, 2 * oversampling * support) qnx = nx // oversampling qny = ny // oversampling cf.data[...] = 0.0 subim = copy_image(im) ccell = onx * numpy.abs(d2r * subim.wcs.wcs.cdelt[0]) / qnx subim.data = numpy.zeros([nchan, npol, qny, qnx]) subim.wcs.wcs.cdelt[0] = -ccell / d2r subim.wcs.wcs.cdelt[1] = +ccell / d2r subim.wcs.wcs.crpix[0] = qnx // 2 + 1.0 subim.wcs.wcs.crpix[1] = qny // 2 + 1.0 if use_aaf: this_pswf_gcf, _ = create_pswf_convolutionfunction(subim, oversampling=1, support=6) norm = 1.0 / this_pswf_gcf.data else: norm = 1.0 if make_pb is not None: pb = make_pb(subim) rpb, footprint = reproject_image(pb, subim.wcs, shape=subim.shape) rpb.data[footprint.data < 1e-6] = 0.0 norm *= rpb.data # We might need to work with a larger image padded_shape = [nchan, npol, ny, nx] thisplane = copy_image(subim) thisplane.data = numpy.zeros(thisplane.shape, dtype='complex') for z, w in enumerate(w_list): thisplane.data[...] = 0.0 + 0.0j thisplane = create_w_term_like(thisplane, w, dopol=True) thisplane.data *= norm paddedplane = pad_image(thisplane, padded_shape) paddedplane = fft_image(paddedplane) ycen, xcen = ny // 2, nx // 2 for y in range(oversampling): ybeg = y + ycen + (support * oversampling) // 2 - oversampling // 2 yend = y + ycen - (support * oversampling) // 2 - oversampling // 2 # vv = range(ybeg, yend, -oversampling) for x in range(oversampling): xbeg = x + xcen + (support * oversampling) // 2 - oversampling // 2 xend = x + xcen - (support * oversampling) // 2 - oversampling // 2 # uu = range(xbeg, xend, -oversampling) cf.data[..., z, y, x, :, :] = paddedplane.data[..., ybeg:yend:-oversampling, xbeg:xend:-oversampling] # for chan in range(nchan): # for pol in range(npol): # cf.data[chan, pol, z, y, x, :, :] = paddedplane.data[chan, pol, :, :][vv, :][:, uu] cf.data /= numpy.sum( numpy.real(cf.data[0, 0, nw // 2, oversampling // 2, oversampling // 2, :, :])) cf.data = numpy.conjugate(cf.data) #==================================== #Use ASKAPSoft routine to crop the support size crop_ASKAPSOft_like = True if crop_ASKAPSOft_like: #Hardcode the cellsize: 1 / FOV #uv_cellsize = 57.3;#N=1200 pixel and pixelsize is 3 arcseconds #uv_cellsize = 43.97;#N=1600 pixel and pixelsize is 3 arcseconds #uv_cellsize = 114.6;#N=1800 pixel with 1 arcsecond pixelsize #uv_cellsize = 57.3;#N=1800 pixel with 2 arcsecond pixelsize #uv_cellsize = 1145.91509915;#N=1800 pixxel with 0.1 arcsecond pixelsize #Get from **kwargs if kwargs is None: #Safe solution works for baselines up to > 100km and result in small kernels uv_cellsize = 1145.91509915 #N=1800 pixxel with 0.1 arcsecond pixelsize if 'UVcellsize' in kwargs.keys(): uv_cellsize = kwargs['UVcellsize'] #print(uv_cellsize); #Cutoff param in ASKAPSoft hardcoded as well ASKAPSoft_cutof = 0.1 wTheta_list = numpy.zeros(len(w_list)) for i in range(0, len(w_list)): if w_list[i] == 0: wTheta_list[i] = 0.9 #This is due to the future if statements cause if it is small, the kernel will be 3 which is a clear cutoff else: wTheta_list[i] = numpy.fabs( w_list[i]) / (uv_cellsize * uv_cellsize) kernel_size_list = [] #We rounded the kernels according to conventional rounding rules for i in range(0, len(wTheta_list)): #if wTheta_list[i] < 1: if wTheta_list[i] < 1: #Change to ASKAPSoft kernel_size_list.append(int(3.)) elif ASKAPSoft_cutof < 0.01: kernel_size_list.append(int(6 + 1.14 * wTheta_list[i])) else: kernel_size_list.append( int(numpy.sqrt(49 + wTheta_list[i] * wTheta_list[i]))) log.info('W-kernel w-terms:') log.info(w_list) log.info('Corresponding w-kernel sizes:') log.info(kernel_size_list) print(numpy.unique(kernel_size_list)) #print(kernel_size_list); crop_list = [] #another rounding according to conventional rounding rules for i in range(0, len(kernel_size_list)): if support - kernel_size_list[i] <= 0: crop_list.append(int(0)) else: crop_list.append(int((support - kernel_size_list[i]) / 2)) #Crop original suppor for i in range(0, nw): if crop_list[i] != 0: cf.data[0, 0, i, :, :, 0:crop_list[i], :] = 0 cf.data[0, 0, i, :, :, -crop_list[i]:, :] = 0 cf.data[0, 0, i, :, :, :, 0:crop_list[i]] = 0 cf.data[0, 0, i, :, :, :, -crop_list[i]:] = 0 else: pass #Plot #import matplotlib.pyplot as plt #cf.data[0,0,i,0,0,...][cf.data[0,0,i,0,0,...] != 0.] = 1+0.j; #plt.imshow(numpy.real(cf.data[0,0,i,0,0,...])) #plt.show(block=True) #plt.close(); #==================================== if use_aaf: pswf_gcf, _ = create_pswf_convolutionfunction(im, oversampling=1, support=6) else: pswf_gcf = create_empty_image_like(im) pswf_gcf.data[...] = 1.0 return pswf_gcf, cf
def sum_images(imagelist): out = copy_image(imagelist[0]) out.data += imagelist[1].data return out
def ingest_visibility(self, freq=None, chan_width=None, times=None, add_errors=False, block=True, bandpass=False): if freq is None: freq = [1e8] if chan_width is None: chan_width = [1e6] if times is None: times = (numpy.pi / 12.0) * numpy.linspace(-3.0, 3.0, 5) lowcore = create_named_configuration('LOWBD2', rmax=750.0) 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=frequency, phasecentre=phasecentre, polarisation_frame=PolarisationFrame("stokesI")) nchan = len(self.frequency) flux = numpy.array(nchan * [[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( direction=sc, flux=flux, frequency=frequency, polarisation_frame=PolarisationFrame("stokesI")) comps.append(comp) if block: predict_skycomponent_visibility(vt, comps) else: predict_skycomponent_visibility(vt, comps) insert_skycomponent(model, comps) self.comps = comps self.model = copy_image(model) self.empty_model = create_empty_image_like(model) export_image_to_fits( model, '%s/test_pipeline_functions_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) if bandpass: bgt = create_gaintable_from_blockvisibility(vt, timeslice=1e5) bgt = simulate_gaintable(bgt, phase_error=0.01, amplitude_error=0.01, smooth_channels=4) vt = apply_gaintable(vt, bgt) return vt
plt.show() plt.clf() show_image(im, chan=noise_channel) plt.title('Noise image %s' % (basename)) plt.savefig('simulation_noise_channel_%d.png' % signal_channel) plt.show() print(im) imfft = fft_image(im) print(imfft) omega = numpy.pi * resolution**2 / (4 * numpy.log(2.0)) wavelength = consts.c / numpy.average(im.frequency) kperjy = 1e-26 * wavelength**2 / (2 * consts.k_B * omega) im_spectrum = copy_image(imfft) im_spectrum.data = kperjy.value * numpy.abs(imfft.data) plt.clf() show_image(im_spectrum, chan=signal_channel, vmax=0.01 * numpy.max(im_spectrum.data[signal_channel, ...])) plt.gca().set_title("Amplitude(FFT(image)) %s" % (basename)) plt.tight_layout() plt.savefig('power_spectrum_image_channel_%d.png' % signal_channel) plt.show() noisy = numpy.max(im_spectrum.data[noise_channel, 0]) > 0.0 if noisy: plt.clf() show_image(im_spectrum, chan=noise_channel, vmax=0.01 * numpy.max(im_spectrum.data[noise_channel, ...]))
zernikes = list() default_vp = create_vp_generic_numeric(model, pointingcentre=None, diameter=15.0, blockage=0.0, taper='gaussian', edge=0.03162278, padding=2, use_local=True) key_nolls = [3, 5, 6, 7] for noll in key_nolls: zernike = {'coeff': 1.0, 'noll': noll} zernike['vp'] = create_vp_generic_numeric(model, pointingcentre=None, diameter=15.0, blockage=0.0, taper='gaussian', edge=0.03162278, zernikes=[zernike], padding=2, use_local=True) zernikes.append(zernike) for trial in range(ntrials): coeffs = numpy.random.normal(0.0, 0.03, len(key_nolls)) vp = copy_image(default_vp) for i in range(len(key_nolls)): vp.data += coeffs[i] * zernikes[i]['vp'].data vp.data = vp.data / numpy.max(numpy.abs(vp.data)) vp_data = vp.data / numpy.max(numpy.abs(vp.data)) vp.data = numpy.real(vp_data) print(trial, qa_image(vp)) export_image_to_fits(vp, "%s/test_voltage_pattern_real_%s_trial%d.fits" % (dir, 'MID_RANDOM_ZERNIKES', trial)) row = (trial - 1) // 4 col = (trial - 1) - 4 * row ax = axs[row, col] ax.imshow(vp.data[0, 0], vmax=0.01, vmin=-0.001) # ax.set_title('Noll %d' % noll) ax.axis('off')
plt.ylabel('Amp Visibility') plt.title('Field %d' % (field)) plt.show() cellsize = 0.00001 model = create_image_from_visibility( vis_list[0], cellsize=cellsize, npixel=512, nchan=1, frequency=[0.5 * (8435100000.0 + 8.4851e+09)], channel_bandwidth=[1e8], imagecentre=vis_list[0].phasecentre, polarisation_frame=PolarisationFrame('stokesIQUV')) mosaic = copy_image(model) mosaicsens = copy_image(model) work = copy_image(model) for vt in vis_list: channel_model = create_image_from_visibility( vt, cellsize=cellsize, npixel=512, nchan=1, imagecentre=vis_list[0].phasecentre, polarisation_frame=PolarisationFrame('stokesIQUV')) beam = create_pb(channel_model, telescope='VLA', pointingcentre=vt.phasecentre,
# In[8]: show_image(beam, components=all_components, cm='Greys', title='Primary beam plus all components', vmax=3.0) lprint("Number of components %d" % len(all_components)) # ### Now show all components with color denoting the nearest bright component, and an image with each pixel filled with the index of the nearest bright component # In[9]: vor, vor_array = voronoi_decomposition(beam, filtered_bright_components) vor_image = copy_image(beam) vor_image.data[...] = vor_array show_image( vor_image, cm='Greys', title='Voronoi partitioning with all components shown, contour at 10% beam', vmax=3 * numpy.max(vor_array)) comps_lists = partition_skycomponent_neighbours(all_components, filtered_bright_components) for comp_id, comps in enumerate(comps_lists): flux = numpy.sum([c.flux[0, 0] for c in comps]) directions = SkyCoord([u.rad * c.direction.ra.rad for c in comps], [u.rad * c.direction.dec.rad for c in comps])