Ejemplo n.º 1
0
    def test_phase_rotate(self):

        uvw = numpy.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)])

        pos = [
            SkyCoord(17, 35, unit=u.deg),
            SkyCoord(17, 30, unit=u.deg),
            SkyCoord(12, 30, unit=u.deg),
            SkyCoord(11, 35, unit=u.deg),
            SkyCoord(51, 35, unit=u.deg),
            SkyCoord(15, 70, unit=u.deg)
        ]

        # Sky coordinates to reproject to
        for phasecentre in pos:
            for newphasecentre in pos:

                # Rotate UVW
                xyz = uvw_to_xyz(uvw, -phasecentre.ra.rad, phasecentre.dec.rad)
                uvw_rotated = xyz_to_uvw(xyz, -newphasecentre.ra.rad,
                                         newphasecentre.dec.rad)

                # Determine phasor
                l_p, m_p, n_p = skycoord_to_lmn(phasecentre, newphasecentre)
                phasor = simulate_point(uvw_rotated, l_p, m_p)

                for sourcepos in pos:
                    # Simulate visibility at old and new phase centre
                    l, m, _ = skycoord_to_lmn(sourcepos, phasecentre)
                    vis = simulate_point(uvw, l, m)
                    l_r, m_r, _ = skycoord_to_lmn(sourcepos, newphasecentre)
                    vis_rotated = simulate_point(uvw_rotated, l_r, m_r)

                    # Difference should be given by phasor
                    assert_allclose(vis * phasor, vis_rotated, atol=1e-10)
Ejemplo n.º 2
0
def predict_skycomponent_visibility(
        vis: Union[Visibility, BlockVisibility],
        sc: Union[Skycomponent, List[Skycomponent]]) -> Visibility:
    """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 not isinstance(sc, collections.Iterable):
        sc = [sc]

    if isinstance(vis, Visibility):

        _, im_nchan = list(get_frequency_map(vis, None))
        npol = vis.polarisation_frame.npol

        for comp in sc:

            assert_same_chan_pol(vis, comp)

            l, m, n = skycoord_to_lmn(comp.direction, vis.phasecentre)
            phasor = simulate_point(vis.uvw, l, m)
            for ivis in range(vis.nvis):
                for pol in range(npol):
                    vis.data['vis'][ivis, pol] += comp.flux[im_nchan[ivis],
                                                            pol] * phasor[ivis]

    elif isinstance(vis, BlockVisibility):

        nchan = vis.nchan
        npol = vis.npol

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

        for comp in sc:
            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)
            for chan in range(nchan):
                phasor = simulate_point(vis.uvw * k[chan], l, m)
                for pol in range(npol):
                    vis.data['vis'][..., chan,
                                    pol] += flux[chan, pol] * phasor[...]

    return vis
Ejemplo n.º 3
0
def predict_skycomponent_visibility(
        vis: Visibility, sc: Union[Skycomponent,
                                   List[Skycomponent]]) -> Visibility:
    """Predict the visibility from a Skycomponent, add to existing visibility, for Visibility

    :param vis: Visibility
    :param sc: Skycomponent or list of SkyComponents
    :return: Visibility
    """
    assert type(vis) is Visibility, "vis is not a Visibility: %r" % vis

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

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

    npol = vis.polarisation_frame.npol

    for comp in sc:

        l, m, n = skycoord_to_lmn(comp.direction, vis.phasecentre)
        phasor = simulate_point(vis.uvw, l, m)
        for ivis in range(vis.nvis):
            for pol in range(npol):
                vis.data['vis'][ivis, pol] += comp.flux[ichan[ivis],
                                                        pol] * phasor[ivis]

            # coords = phasor, ichan
            # for pol in range(npol):
            #     vis.data['vis'][:,pol] += [comp.flux[ic, pol] * p for p, ic in zip(*coords)]

    return vis
Ejemplo n.º 4
0
def sum_visibility(vis: Visibility, direction: SkyCoord) -> numpy.array:
    """ Direct Fourier summation in a given direction

    :param vis: Visibility to be summed
    :param direction: Direction of summation
    :return: flux[nch,npol], weight[nch,pol]
    """
    # TODO: Convert to Visibility or remove?

    svis = copy_visibility(vis)

    l, m, n = skycoord_to_lmn(direction, svis.phasecentre)
    phasor = numpy.conjugate(simulate_point(svis.uvw, l, m))

    # Need to put correct mapping here
    _, frequency = get_frequency_map(svis, None)

    frequency = list(frequency)

    nchan = max(frequency) + 1
    npol = svis.polarisation_frame.npol

    flux = numpy.zeros([nchan, npol])
    weight = numpy.zeros([nchan, npol])

    coords = svis.vis, svis.weight, phasor, list(frequency)
    for v, wt, p, ic in zip(*coords):
        for pol in range(npol):
            flux[ic, pol] += numpy.real(wt[pol] * v[pol] * p)
            weight[ic, pol] += wt[pol]

    flux[weight > 0.0] = flux[weight > 0.0] / weight[weight > 0.0]
    flux[weight <= 0.0] = 0.0
    return flux, weight
Ejemplo n.º 5
0
 def test_simulate_point(self):
     # Prepare a synthetic layout
     uvw = numpy.concatenate(numpy.concatenate(numpy.transpose(numpy.mgrid[-3:4, -3:4, 0:1])))
     bls = baselines(uvw)
     
     # Should have positive amplitude for the middle of the picture
     vis = simulate_point(bls, 0, 0)
     assert_allclose(vis, numpy.ones(len(vis)))
     
     # For the half-way point the result is either -1 or 1
     # depending on whether the baseline length is even
     bl_even = 1 - 2 * (numpy.sum(bls, axis=1) % 2)
     vis = simulate_point(bls, 0.5, 0.5)
     assert_allclose(vis, bl_even)
     vis = simulate_point(bls, -0.5, 0.5)
     assert_allclose(vis, bl_even)
     vis = simulate_point(bls, 0.5, -0.5)
     assert_allclose(vis, bl_even)
     vis = simulate_point(bls, -0.5, -0.5)
     assert_allclose(vis, bl_even)
Ejemplo n.º 6
0
def phaserotate_visibility(vis: Visibility, newphasecentre: SkyCoord, tangent=True, inverse=False) -> Visibility:
    """
    Phase rotate from the current phase centre to a new phase centre

    If tangent is False the uvw are recomputed and the visibility phasecentre is updated.
    Otherwise only the visibility phases are adjusted

    :param vis: Visibility to be rotated
    :param newphasecentre:
    :param tangent: Stay on the same tangent plane? (True)
    :param inverse: Actually do the opposite
    :return: Visibility
    """
    assert isinstance(vis, Visibility), "vis is not a Visibility: %r" % vis

    l, m, n = skycoord_to_lmn(newphasecentre, vis.phasecentre)

    # No significant change?
    if numpy.abs(n) > 1e-15:

        # Make a new copy
        newvis = copy_visibility(vis)

        phasor = simulate_point(newvis.uvw, l, m)
        nvis, npol = vis.vis.shape
        # TODO: Speed up (broadcast rules not obvious to me)
        if inverse:
            for i in range(nvis):
                for pol in range(npol):
                    newvis.data['vis'][i, pol] *= phasor[i]
        else:
            for i in range(nvis):
                for pol in range(npol):
                    newvis.data['vis'][i, pol] *= numpy.conj(phasor[i])
        
        # To rotate UVW, rotate into the global XYZ coordinate system and back. We have the option of
        # staying on the tangent plane or not. If we stay on the tangent then the raster will
        # join smoothly at the edges. If we change the tangent then we will have to reproject to get
        # the results on the same image, in which case overlaps or gaps are difficult to deal with.
        if not tangent:
            if inverse:
                xyz = uvw_to_xyz(vis.data['uvw'], ha=-newvis.phasecentre.ra.rad, dec=newvis.phasecentre.dec.rad)
                newvis.data['uvw'][...] = \
                    xyz_to_uvw(xyz, ha=-newphasecentre.ra.rad, dec=newphasecentre.dec.rad)[...]
            else:
                # This is the original (non-inverse) code
                xyz = uvw_to_xyz(newvis.data['uvw'], ha=-newvis.phasecentre.ra.rad, dec=newvis.phasecentre.dec.rad)
                newvis.data['uvw'][...] = xyz_to_uvw(xyz, ha=-newphasecentre.ra.rad, dec=newphasecentre.dec.rad)[
                    ...]
            newvis.phasecentre = newphasecentre
        return newvis
    else:
        return vis
Ejemplo n.º 7
0
def predict_skycomponent_blockvisibility(vis: BlockVisibility,
                                         sc: Union[Skycomponent,
                                                   List[Skycomponent]],
                                         **kwargs) -> BlockVisibility:
    """Predict the visibility from a Skycomponent, add to existing visibility, for BlockVisibility

    :param vis: BlockVisibility
    :param sc: Skycomponent or list of SkyComponents
    :param spectral_mode: {mfs|channel} (channel)
    :return: BlockVisibility
    """
    assert type(
        vis) is BlockVisibility, "vis is not a BlockVisibility: %r" % vis

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

    nchan = vis.nchan
    npol = vis.npol

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

    k = vis.frequency / constants.c.to('m/s').value

    for comp in sc:

        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)
        for chan in range(nchan):
            phasor = simulate_point(vis.uvw * k[chan], l, m)
            for pol in range(npol):
                vis.data['vis'][..., chan,
                                pol] += flux[chan, pol] * phasor[...]

    return vis