Пример #1
0
def copy_skymodel(sm):
    """ Copy a sky model

    :param sm: SkyModel to be copied
    :return: SkyModel
    """
    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 partition_skymodel_by_flux(sc, model, flux_threshold=-numpy.inf):
    """Partition skymodel according to flux

    Bright skycomponents are put into a SkyModel as a list, and weak skycomponents
    are inserted into SkyModel as an image.
    
    :param sc: List of skycomponents
    :param model: Model image
    :param flux_threshold:
    :return: SkyModel

    For example::

        fluxes = numpy.linspace(0, 1.0, 11)
        sc = [create_skycomponent(direction=phasecentre, flux=numpy.array([[f]]), frequency=frequency,
                                  polarisation_frame=PolarisationFrame('stokesI')) for f in fluxes]

        sm = partition_skymodel_by_flux(sc, model, flux_threshold=0.31)
        assert len(sm.components) == 7, len(sm.components)

    """
    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)
Пример #3
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:

    For example::

        gaintable = create_gaintable_from_blockvisibility(block_vis)
        mpccal_skymodel = initialize_skymodel_voronoi(model, ical_components, gaintable)

    """
    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
Пример #4
0
def show_skymodel(sms, psf_width=1.75, cm='Greys', vmax=None, vmin=None):
    """ Show a list of SkyModels

    :param sms: List of SkyModels
    :param psf_width: Width of PSF in pixels
    :param cm: matplotlib colormap
    :param vmax: Maximum in image display
    :param vmin: Minimum in image display
    :return:
    """
    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()
Пример #5
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
Пример #6
0
def update_skymodel_from_image(sm, im, damping=0.5):
    """Update a skymodel for an image, applying damping factor

    :param sm: List of skymodels
    :param im: Image
    :return: List of SkyModels
    """
    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
Пример #7
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 = dft_skycomponent_visibility(v, comps)
            else:
                v = dft_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
Пример #8
0
def calculate_skymodel_equivalent_image(sm):
    """Calculate an equivalent image for a skymodel

    Uses the image from the first skymodel as the template for the image

    :param sm: List of skymodels
    :return: Image
    """
    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_cal_sm(ov, sm, g):
        assert isinstance(ov, Visibility), 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 = dft_skycomponent_visibility(v, comps)
            else:
                v = dft_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]

        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
Пример #10
0
def invert_wstack_single(vis: Visibility,
                         im: Image,
                         dopsf,
                         normalize=True,
                         remove=True,
                         gcfcf=None,
                         **kwargs) -> (Image, numpy.ndarray):
    """Process single w slice
    
    The w-stacking or w-slicing approach is to partition the visibility data by slices in w. The measurement equation is
    approximated as:

    .. math::

        V(u,v,w) =\\sum_i \\int \\frac{ I(l,m) e^{-2 \\pi j (w_i(\\sqrt{1-l^2-m^2}-1))})}{\\sqrt{1-l^2-m^2}} e^{-2 \\pi j (ul+vm)} dl dm

    If images constructed from slices in w are added after applying a w-dependent image plane correction, the w term will be corrected.

    :param vis: Visibility to be inverted
    :param im: image template (not changed)
    :param dopsf: Make the psf instead of the dirty image
    :param normalize: Normalize by the sum of weights (True)
    :returns: image, sum of weights
    """
    assert image_is_canonical(im)

    log.debug("invert_wstack_single: predicting using single w slice")

    kwargs['imaginary'] = True

    assert isinstance(
        vis,
        Visibility), "wstack requires Visibility format not BlockVisibility"

    if dopsf:
        vis = fill_vis_for_psf(vis)

    # We might want to do wprojection so we remove the average w
    w_average = numpy.average(vis.w)
    if remove:
        vis.data['uvw'][..., 2] -= w_average

    gcf, cf = gcfcf

    griddata = create_griddata_from_image(im, vis)
    griddata, sumwt = grid_visibility_to_griddata(vis,
                                                  griddata=griddata,
                                                  cf=cf)
    cim = fft_griddata_to_image(griddata, gcf)
    cim = normalize_sumwt(cim, sumwt)

    if remove:
        vis.data['uvw'][..., 2] += w_average

    # Calculate w beam and apply to the model. The imaginary part is not needed
    w_beam = create_w_term_like(im, w_average, vis.phasecentre)
    cworkimage = copy_image(cim)
    #    cworkimage.data = numpy.conjugate(w_beam.data) * cim.data
    cworkimage.data = w_beam.data * cim.data
    workimage = convert_polimage_to_stokes(cworkimage)

    return workimage, sumwt
    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 = False
        if export:
            export_image_to_fits(
                vp, "%s/test_voltage_pattern_real_%s_trial%d.fits" %
                (dir, 'MID_RANDOM_ZERNIKES', trial))

        row = (trial - 1) // 4
 def sum_images(imagelist):
     out = copy_image(imagelist[0])
     out.data += imagelist[1].data
     return out
Пример #13
0
    def _test(self, time_range=None, flux=None, test_vp=False, name=""):
        # Set up details of simulated observation

        npixel = 1024
        band = 'B2'
        frequency = [1.36e9]
        rmax = 1e3

        self.createVis(rmax=rmax)

        if time_range is None:
            time_range = [-0.01, 0.01]
        time_chunk = 1800.0
        integration_time = 1800.0
        imaging_context = "2d"
        cellsize = 1e-05
        vis_slices = 1
        telescope = "MID_FEKO_B2"

        result = dict()

        if flux is None:
            flux = [[1.0, 0.0, 0.0, 0.0]]
        else:
            flux = [flux]

        cellsize_deg = 180.0 * cellsize / numpy.pi
        offset = [0.0, 0.25 - 0.3309316221544 * cellsize_deg]
        ra = self.phasecentre.ra.deg
        dec = self.phasecentre.dec.deg
        print(ra, dec)
        odirection = SkyCoord(
            ra=(ra + offset[0] / numpy.cos(numpy.pi * dec / 180.0)) * u.deg,
            dec=(dec + offset[1]) * u.deg,
            frame='icrs',
            equinox='J2000')
        print(self.phasecentre)
        print(odirection)

        original_components = [
            Skycomponent(direction=odirection,
                         frequency=frequency,
                         flux=flux,
                         polarisation_frame=PolarisationFrame('stokesIQUV'))
        ]

        for method in ["fft", "dft"]:

            bvis_graph = create_standard_mid_simulation_rsexecute_workflow(
                band,
                rmax,
                self.phasecentre,
                time_range,
                time_chunk,
                integration_time,
                polarisation_frame=PolarisationFrame("linear"),
                zerow=True)  #imaging_context == "2d")
            bvis_graph = rsexecute.persist(bvis_graph)

            def find_vp_actual(telescope, normalise=True):
                vp = create_vp(telescope=telescope)
                if test_vp:
                    vp.data[:, 0, ...] = 1.0
                    vp.data[:, 1, ...] = 0.0
                    vp.data[:, 2, ...] = 0.0
                    vp.data[:, 3, ...] = 1.0
                if normalise:
                    g = numpy.zeros([4])
                    g[0] = numpy.max(numpy.abs(vp.data[:, 0, ...]))
                    g[3] = numpy.max(numpy.abs(vp.data[:, 3, ...]))
                    g[1] = g[2] = numpy.sqrt(g[0] * g[3])
                    for chan in range(4):
                        vp.data[:, chan, ...] /= g[chan]
                return vp

            future_model_list = [
                rsexecute.execute(create_image_from_visibility)(
                    bvis,
                    npixel=npixel,
                    frequency=frequency,
                    nchan=1,
                    cellsize=cellsize,
                    phasecentre=self.phasecentre,
                    polarisation_frame=PolarisationFrame("stokesIQUV"))
                for bvis in bvis_graph
            ]

            centre_model = \
                [rsexecute.execute(create_image_from_visibility)(v, npixel=npixel,
                                                                 nchan=1,
                                                                 cellsize=cellsize,
                                                                 phasecentre=self.phasecentre,
                                                                 polarisation_frame=PolarisationFrame("stokesIQUV"))
                 for v in bvis_graph]
            centre_model = rsexecute.persist(centre_model)

            # Now make all the residual images:
            if method == "dft":
                # The parallactic angle rotation is done when the voltage pattern is
                # converted to a gaintable
                def make_ejterm(model):
                    vp = find_vp_actual(telescope=telescope)
                    return vp

                vp_list = [
                    rsexecute.execute(make_ejterm)(centre_model[ibvis])
                    for ibvis, bvis in enumerate(bvis_graph)
                ]
                vp_list = rsexecute.persist(vp_list)
                gt_list = [
                    rsexecute.execute(simulate_gaintable_from_voltage_pattern)(
                        bvis,
                        original_components,
                        vp_list[ibv],
                        use_radec=False) for ibv, bvis in enumerate(bvis_graph)
                ]
                gt_list = rsexecute.persist(gt_list)
                dirty_list = \
                    calculate_residual_dft_rsexecute_workflow(bvis_graph, original_components,
                                                              future_model_list,
                                                              gt_list=gt_list,
                                                              context=imaging_context,
                                                              vis_slices=vis_slices,
                                                              do_wstacking=False)
                dirty_list = rsexecute.persist(dirty_list)

            else:

                def make_ejterm_rotated(model, bvis):
                    vp = find_vp_actual(telescope=telescope)
                    pa = numpy.average(
                        calculate_blockvisibility_parallactic_angles(bvis))
                    vp_rotated = convert_azelvp_to_radec(vp, model, -pa)
                    return vp_rotated

                vp_list = [
                    rsexecute.execute(make_ejterm_rotated)(centre_model[ibvis],
                                                           bvis)
                    for ibvis, bvis in enumerate(bvis_graph)
                ]
                vp_list = rsexecute.persist(vp_list)

                dirty_list = \
                    calculate_residual_fft_rsexecute_workflow(bvis_graph, original_components,
                                                              future_model_list, vp_list=vp_list,
                                                              context=imaging_context,
                                                              vis_slices=vis_slices,
                                                              do_wstacking=False)
                dirty_list = rsexecute.persist(dirty_list)

            dirty_list = rsexecute.compute(dirty_list, sync=True)

            for ipol, pol in enumerate(["I", "Q", "U", "V"]):
                result["model_{}".format(pol)] = flux[0][ipol]
                polimage = copy_image(dirty_list[0])
                polimage.data = polimage.data[:, ipol, ...][:, numpy.newaxis,
                                                            ...]
                qa = qa_image(polimage, context="Stokes " + pol)
                result["peak_{}_{}".format(method, pol)] = max(qa.data['min'],
                                                               qa.data['max'],
                                                               key=abs)
            export_image_to_fits(
                dirty_list[0],
                "{}/test_voltage_pattern_pol_rsexecute_{}_{}.fits".format(
                    self.dir, name, method))

        if self.verbose:
            print(name)
        for ipol, pol in enumerate(["I", "Q", "U", "V"]):
            result["peak_diff_{}".format(pol)] = result["peak_fft_{}".format(
                pol)] - result["peak_dft_{}".format(pol)]
            result["peak_modeldiff_{}".format(pol)] = result[
                "peak_dft_{}".format(pol)] - result["model_{}".format(pol)]
            if self.verbose:
                print(
                    "{} model: {:.2f} fft: {:.6f} dft: {:.6f} fft - dft: {:.6f} dft - model: {:.6f}"
                    .format(pol, result["model_{}".format(pol)],
                            result["peak_fft_{}".format(pol)],
                            result["peak_dft_{}".format(pol)],
                            result["peak_diff_{}".format(pol)],
                            result["peak_modeldiff_{}".format(pol)]))

        return result