예제 #1
0
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)
예제 #2
0
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
예제 #5
0
    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
예제 #7
0
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)
예제 #8
0
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)
예제 #9
0
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
예제 #11
0
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
예제 #12
0
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
예제 #13
0
    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)
예제 #16
0
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
예제 #18
0
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()
예제 #19
0
                 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]
예제 #20
0
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
예제 #21
0
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
예제 #24
0
    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,
예제 #27
0
# 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])