Esempio n. 1
0
def predict_skycomponent_visibility(
    vis: Union[Visibility, BlockVisibility], sc: Union[Skycomponent,
                                                       List[Skycomponent]]
) -> Union[Visibility, BlockVisibility]:
    """Predict the visibility from a Skycomponent, add to existing visibility, for Visibility or BlockVisibility

    :param vis: Visibility or BlockVisibility
    :param sc: Skycomponent or list of SkyComponents
    :return: Visibility or BlockVisibility
    """
    if sc is None:
        return vis

    if not isinstance(sc, collections.Iterable):
        sc = [sc]

    if isinstance(vis, Visibility):

        _, im_nchan = list(get_frequency_map(vis, None))

        for comp in sc:
            assert isinstance(comp, Skycomponent), comp

            assert_same_chan_pol(vis, comp)

            l, m, n = skycoord_to_lmn(comp.direction, vis.phasecentre)
            phasor = simulate_point(vis.uvw, l, m)

            comp_flux = comp.flux[im_nchan, :]
            vis.data['vis'][...] += comp_flux[:, :] * phasor[:, numpy.newaxis]

    elif isinstance(vis, BlockVisibility):

        ntimes, nant, _, nchan, npol = vis.vis.shape

        k = numpy.array(vis.frequency) / constants.c.to('m s^-1').value

        for comp in sc:
            #            assert isinstance(comp, Skycomponent), comp
            assert_same_chan_pol(vis, comp)

            flux = comp.flux
            if comp.polarisation_frame != vis.polarisation_frame:
                flux = convert_pol_frame(flux, comp.polarisation_frame,
                                         vis.polarisation_frame)

            l, m, n = skycoord_to_lmn(comp.direction, vis.phasecentre)
            uvw = vis.uvw[..., numpy.newaxis] * k
            phasor = numpy.ones([ntimes, nant, nant, nchan, npol],
                                dtype='complex')
            for chan in range(nchan):
                phasor[:, :, :,
                       chan, :] = simulate_point(uvw[..., chan], l,
                                                 m)[..., numpy.newaxis]

            vis.data['vis'][..., :, :] += flux[:, :] * phasor[..., :]

    return vis
Esempio n. 2
0
def idft_visibility_skycomponent(vis: Union[Visibility, BlockVisibility],
                                 sc: Union[Skycomponent, List[Skycomponent]]) -> \
        ([Skycomponent, List[Skycomponent]], List[numpy.ndarray]):
    """Inverse DFT a Skycomponent from Visibility or BlockVisibility

    :param vis: Visibility or BlockVisibility
    :param sc: Skycomponent or list of SkyComponents
    :return: Skycomponent or list of SkyComponents, array of weights
    """
    if sc is None:
        return sc

    if not isinstance(sc, collections.abc.Iterable):
        sc = [sc]

    newsc = list()
    weights_list = list()

    for comp in sc:
        assert isinstance(comp, Skycomponent), comp
        assert_same_chan_pol(vis, comp)
        newcomp = copy_skycomponent(comp)

        if isinstance(vis, Visibility):

            flux = numpy.zeros_like(comp.flux, dtype='complex')
            weight = numpy.zeros_like(comp.flux, dtype='float')
            _, im_nchan = list(get_frequency_map(vis, None))
            phasor = numpy.conjugate(
                calculate_visibility_phasor(comp.direction, vis))
            fvwp = vis.flagged_weight * vis.flagged_vis * phasor
            fw = vis.flagged_weight
            for row in range(vis.nvis):
                ic = im_nchan[row]
                flux[ic, :] += fvwp[row, :]
                weight[ic, :] += fw[row, :]

        elif isinstance(vis, BlockVisibility):

            phasor = numpy.conjugate(
                calculate_blockvisibility_phasor(comp.direction, vis))
            flux = numpy.sum(vis.flagged_weight * vis.flagged_vis * phasor,
                             axis=(0, 1, 2))
            weight = numpy.sum(vis.flagged_weight, axis=(0, 1, 2))

        flux[weight > 0.0] = flux[weight > 0.0] / weight[weight > 0.0]
        flux[weight <= 0.0] = 0.0
        if comp.polarisation_frame != vis.polarisation_frame:
            flux = convert_pol_frame(flux, vis.polarisation_frame,
                                     comp.polarisation_frame)

        newcomp.flux = flux

        newsc.append(newcomp)
        weights_list.append(weight)

    return newsc, weights_list
Esempio n. 3
0
def apply_beam_to_skycomponent(sc: Union[Skycomponent, List[Skycomponent]], beam: Image) \
        -> Union[Skycomponent, List[Skycomponent]]:
    """ Insert a Skycomponent into an image

    :param beam:
    :param sc: SkyComponent or list of SkyComponents
    :return: List of skycomponents
    """
    assert isinstance(beam, Image)
    single = not isinstance(sc, collections.Iterable)

    if single:
        sc = [sc]

    nchan, npol, ny, nx = beam.shape

    log.debug('apply_beam_to_skycomponent: Processing %d components' %
              (len(sc)))

    ras = [comp.direction.ra.radian for comp in sc]
    decs = [comp.direction.dec.radian for comp in sc]
    skycoords = SkyCoord(ras * u.rad, decs * u.rad, frame='icrs')
    pixlocs = skycoord_to_pixel(skycoords, beam.wcs, origin=1, mode='wcs')

    newsc = []
    total_flux = numpy.zeros([nchan, npol])
    for icomp, comp in enumerate(sc):

        assert comp.shape == 'Point', "Cannot handle shape %s" % comp.shape

        assert_same_chan_pol(beam, comp)

        pixloc = (pixlocs[0][icomp], pixlocs[1][icomp])
        if not numpy.isnan(pixloc).any():
            x, y = int(round(float(pixloc[0]))), int(round(float(pixloc[1])))
            if 0 <= x < nx and 0 <= y < ny:
                comp.flux[:, :] *= beam.data[:, :, y, x]
                total_flux += comp.flux
                newsc.append(
                    Skycomponent(comp.direction,
                                 comp.frequency,
                                 comp.name,
                                 comp.flux,
                                 shape=comp.shape,
                                 polarisation_frame=comp.polarisation_frame))

    log.debug('apply_beam_to_skycomponent: %d components with total flux %s' %
              (len(newsc), total_flux))
    if single:
        return newsc[0]
    else:
        return newsc
Esempio n. 4
0
def dft_skycomponent_visibility(vis: Union[Visibility, BlockVisibility], sc: Union[Skycomponent, List[Skycomponent]]) \
        -> Union[Visibility, BlockVisibility]:
    """DFT to get the visibility from a Skycomponent, for Visibility or BlockVisibility

    :param vis: Visibility or BlockVisibility
    :param sc: Skycomponent or list of SkyComponents
    :return: Visibility or BlockVisibility
    """
    if sc is None:
        return vis

    if not isinstance(sc, collections.abc.Iterable):
        sc = [sc]

    for comp in sc:

        assert_same_chan_pol(vis, comp)
        assert isinstance(comp, Skycomponent), comp
        flux = comp.flux
        if comp.polarisation_frame != vis.polarisation_frame:
            flux = convert_pol_frame(flux, comp.polarisation_frame,
                                     vis.polarisation_frame)

        if isinstance(vis, Visibility):

            _, im_nchan = list(get_frequency_map(vis, None))
            phasor = calculate_visibility_phasor(comp.direction, vis)
            for row in range(vis.nvis):
                ic = im_nchan[row]
                vis.data['vis'][row, :] += flux[ic, :] * phasor[row]

        elif isinstance(vis, BlockVisibility):

            phasor = calculate_blockvisibility_phasor(comp.direction, vis)
            vis.data['vis'] += flux * phasor

    return vis
Esempio n. 5
0
def insert_skycomponent(im: Image,
                        sc: Union[Skycomponent, List[Skycomponent]],
                        insert_method='Nearest',
                        bandwidth=1.0,
                        support=8) -> Image:
    """ Insert a Skycomponent into an image
    
    :param im:
    :param sc: SkyComponent or list of SkyComponents
    :param insert_method: '' | 'Sinc' | 'Lanczos'
    :param bandwidth: Fractional of uv plane to optimise over (1.0)
    :param support: Support of kernel (7)
    :return: image
    """

    assert isinstance(im, Image)

    support = int(support / bandwidth)

    nchan, npol, ny, nx = im.data.shape

    if not isinstance(sc, collections.Iterable):
        sc = [sc]

    log.debug("insert_skycomponent: Using insert method %s" % insert_method)

    image_frequency = im.frequency

    ras = [comp.direction.ra.radian for comp in sc]
    decs = [comp.direction.dec.radian for comp in sc]
    skycoords = SkyCoord(ras * u.rad, decs * u.rad, frame='icrs')
    pixlocs = skycoord_to_pixel(skycoords, im.wcs, origin=0, mode='wcs')

    for icomp, comp in enumerate(sc):

        assert comp.shape == 'Point', "Cannot handle shape %s" % comp.shape

        assert_same_chan_pol(im, comp)
        pixloc = (pixlocs[0][icomp], pixlocs[1][icomp])
        flux = numpy.zeros([nchan, npol])

        if comp.flux.shape[0] > 1:
            for pol in range(npol):
                fint = interpolate.interp1d(comp.frequency,
                                            comp.flux[:, pol],
                                            kind="cubic")
                flux[:, pol] = fint(image_frequency)
        else:
            flux = comp.flux

        if insert_method == "Lanczos":
            insert_array(im.data,
                         pixloc[0],
                         pixloc[1],
                         flux,
                         bandwidth,
                         support,
                         insert_function=insert_function_L)
        elif insert_method == "Sinc":
            insert_array(im.data,
                         pixloc[0],
                         pixloc[1],
                         flux,
                         bandwidth,
                         support,
                         insert_function=insert_function_sinc)
        elif insert_method == "PSWF":
            insert_array(im.data,
                         pixloc[0],
                         pixloc[1],
                         flux,
                         bandwidth,
                         support,
                         insert_function=insert_function_pswf)
        else:
            insert_method = 'Nearest'
            y, x = numpy.round(pixloc[1]).astype('int'), numpy.round(
                pixloc[0]).astype('int')
            if 0 <= x < nx and 0 <= y < ny:
                im.data[:, :, y, x] += flux[...]

    return im
def apply_voltage_pattern_to_skycomponent(sc: Union[Skycomponent, List[Skycomponent]], vp: Image,
                                          inverse=False) \
        -> Union[Skycomponent, List[Skycomponent]]:
    """ Apply a voltage pattern to a Skycomponent

    For inverse==False, input polarisation_frame must be stokesIQUV, and
    output polarisation_frame is same as voltage pattern

    For inverse==True, input polarisation_frame must be same as voltage pattern, and
    output polarisation_frame is "stokesIQUV"

    Requires a complex Image with the correct ordering of polarisation axes:
    e.g. RR, LL, RL, LR or XX, YY, XY, YX

    :param vp: voltage pattern as complex image
    :param sc: SkyComponent or list of SkyComponents
    :return: List of skycomponents
    """
    assert isinstance(vp, Image)
    assert (vp.polarisation_frame == PolarisationFrame("linear")) or \
           (vp.polarisation_frame == PolarisationFrame("circular"))

    assert vp.data.dtype == "complex128"
    single = not isinstance(sc, collections.abc.Iterable)

    if single:
        sc = [sc]

    nchan, npol, ny, nx = vp.shape

    log.debug('apply_vp_to_skycomponent: Processing %d components' % (len(sc)))

    ras = [comp.direction.ra.radian for comp in sc]
    decs = [comp.direction.dec.radian for comp in sc]
    skycoords = SkyCoord(ras * u.rad, decs * u.rad, frame='icrs')
    pixlocs = skycoord_to_pixel(skycoords, vp.wcs, origin=1, mode='wcs')

    newsc = []
    total_flux = numpy.zeros([nchan, npol], dtype="complex")

    for icomp, comp in enumerate(sc):

        assert comp.shape == 'Point', "Cannot handle shape %s" % comp.shape
        assert_same_chan_pol(vp, comp)

        # Convert to linear (xx, xy, yx, yy) or circular (rr, rl, lr, ll)
        nchan, npol = comp.flux.shape
        assert npol == 4
        if not inverse:
            assert comp.polarisation_frame == PolarisationFrame("stokesIQUV")

        comp_flux_cstokes = \
            convert_pol_frame(comp.flux, comp.polarisation_frame, vp.polarisation_frame).reshape([nchan, 2, 2])
        comp_flux = numpy.zeros([nchan, npol], dtype='complex')

        pixloc = (pixlocs[0][icomp], pixlocs[1][icomp])
        if not numpy.isnan(pixloc).any():
            x, y = int(round(float(pixloc[0]))), int(round(float(pixloc[1])))
            if 0 <= x < nx and 0 <= y < ny:
                # Now we want to left and right multiply by the Jones matrices
                # comp_flux = vp.data[:, :, y, x] * comp_flux_cstokes * numpy.vp.data[:, :, y, x]
                for chan in range(nchan):
                    ej = vp.data[chan, :, y, x].reshape([2, 2])
                    cfs = comp_flux_cstokes[chan].reshape([2, 2])
                    comp_flux[chan, :] = apply_jones(ej, cfs,
                                                     inverse).reshape([4])

                total_flux += comp_flux
                if inverse:
                    comp_flux = convert_pol_frame(
                        comp_flux, vp.polarisation_frame,
                        PolarisationFrame("stokesIQUV"))
                    comp.polarisation_frame = PolarisationFrame("stokesIQUV")

                newsc.append(
                    Skycomponent(comp.direction,
                                 comp.frequency,
                                 comp.name,
                                 comp_flux,
                                 shape=comp.shape,
                                 polarisation_frame=vp.polarisation_frame))

    log.debug('apply_vp_to_skycomponent: %d components with total flux %s' %
              (len(newsc), total_flux))
    if single:
        return newsc[0]
    else:
        return newsc