def test_create_visibility_from_rows_makecopy(self):
     self.vis = create_visibility(self.lowcore, self.times, self.frequency, phasecentre=self.phasecentre,
                                       weight=1.0, channel_bandwidth=self.channel_bandwidth)
     rows = self.vis.time > 150.0
     for makecopy in [True, False]:
         selected_vis = create_visibility_from_rows(self.vis, rows, makecopy=makecopy)
         assert selected_vis.nvis == numpy.sum(numpy.array(rows))
Exemple #2
0
 def test_coalesce_decoalesce_with_iter(self):
     for rows in vis_timeslice_iter(self.blockvis):
         visslice = create_visibility_from_rows(self.blockvis, rows)
         cvisslice = convert_blockvisibility_to_visibility(visslice)
         assert numpy.min(cvisslice.frequency) == numpy.min(self.frequency)
         assert numpy.min(cvisslice.frequency) > 0.0
         dvisslice = decoalesce_visibility(cvisslice)
         assert dvisslice.nvis == visslice.nvis
def invert_serial(vis, im: Image, dopsf=False, normalize=True, context='2d', vis_slices=1,
                  facets=1, overlap=0, taper=None, **kwargs):
    """ Invert using algorithm specified by context:

     * 2d: Two-dimensional transform
     * wstack: wstacking with either vis_slices or wstack (spacing between w planes) set
     * wprojection: w projection with wstep (spacing between w places) set, also kernel='wprojection'
     * timeslice: snapshot imaging with either vis_slices or timeslice set. timeslice='auto' does every time
     * facets: Faceted imaging with facets facets on each axis
     * facets_wprojection: facets AND wprojection
     * facets_wstack: facets AND wstacking
     * wprojection_wstack: wprojection and wstacking


    :param vis:
    :param im:
    :param dopsf: Make the psf instead of the dirty image (False)
    :param normalize: Normalize by the sum of weights (True)
    :param context: Imaging context e.g. '2d', 'timeslice', etc.
    :param kwargs:
    :return: Image, sum of weights
    """
    c = imaging_context(context)
    vis_iter = c['vis_iterator']
    invert = c['invert']

    if not isinstance(vis, Visibility):
        svis = convert_blockvisibility_to_visibility(vis)
    else:
        svis = vis
    
    resultimage = create_empty_image_like(im)
    
    totalwt = None
    for rows in vis_iter(svis, vis_slices=vis_slices):
        if numpy.sum(rows):
            visslice = create_visibility_from_rows(svis, rows)
            sumwt = 0.0
            workimage = create_empty_image_like(im)
            for dpatch in image_scatter_facets(workimage, facets=facets, overlap=overlap, taper=taper):
                result, sumwt = invert(visslice, dpatch, dopsf, normalize=False, facets=facets,
                                       vis_slices=vis_slices, **kwargs)
                # Ensure that we fill in the elements of dpatch instead of creating a new numpy arrray
                dpatch.data[...] = result.data[...]
            # Assume that sumwt is the same for all patches
            if totalwt is None:
                totalwt = sumwt
            else:
                totalwt += sumwt
            resultimage.data += workimage.data
    
    assert totalwt is not None, "No valid data found for imaging"
    if normalize:
        resultimage = normalize_sumwt(resultimage, totalwt)
    
    return resultimage, totalwt
Exemple #4
0
 def test_vis_wslice_iterator(self):
     self.actualSetUp()
     nchunks = vis_wslices(self.vis, wslice=10.0)
     log.debug('Found %d chunks' % (nchunks))
     assert nchunks > 1
     total_rows = 0
     for chunk, rows in enumerate(vis_wslice_iter(self.vis, nchunks)):
         assert len(rows)
         visslice = create_visibility_from_rows(self.vis, rows)
         total_rows += visslice.nvis
         assert numpy.sum(visslice.nvis) < self.vis.nvis
     assert total_rows == self.vis.nvis, "Total rows iterated %d, Original rows %d" % (
         total_rows, self.vis.nvis)
Exemple #5
0
def uv_cut(vis, uv_max):
    """Cut the visibility data at uv-distances beyond uvmax.
        
    Args:
    vis (obj): ARL visibility data.
    uv_max (float): maximum uv-coordinate.
    
    Returns:
    vis: New visibility data.
    """
    # Cut off data beyond the maximum uv-distance:
    uv_dist = np.sqrt(vis.data['uvw'][:, 0]**2 + vis.data['uvw'][:, 1]**2)
    vis = create_visibility_from_rows(vis, uv_dist < uv_max)
    return vis
def predict_serial(vis, model: Image, context='2d', vis_slices=1, facets=1, overlap=0, taper=None,
                   **kwargs) -> Visibility:
    """Predict visibilities using algorithm specified by context
    
     * 2d: Two-dimensional transform
     * wstack: wstacking with either vis_slices or wstack (spacing between w planes) set
     * wprojection: w projection with wstep (spacing between w places) set, also kernel='wprojection'
     * timeslice: snapshot imaging with either vis_slices or timeslice set. timeslice='auto' does every time
     * facets: Faceted imaging with facets facets on each axis
     * facets_wprojection: facets AND wprojection
     * facets_wstack: facets AND wstacking
     * wprojection_wstack: wprojection and wstacking

    
    :param vis:
    :param model: Model image, used to determine image characteristics
    :param context: Imaging context e.g. '2d', 'timeslice', etc.
    :param inner: Inner loop 'vis'|'image'
    :param kwargs:
    :return:


    """
    c = imaging_context(context)
    vis_iter = c['vis_iterator']
    predict = c['predict']
    
    if not isinstance(vis, Visibility):
        svis = convert_blockvisibility_to_visibility(vis)
    else:
        svis = vis
    
    result = copy_visibility(vis, zero=True)
    
    for rows in vis_iter(svis, vis_slices=vis_slices):
        if numpy.sum(rows):
            visslice = create_visibility_from_rows(svis, rows)
            visslice.data['vis'][...] = 0.0
            for dpatch in image_scatter_facets(model, facets=facets, overlap=overlap, taper=taper):
                result.data['vis'][...] = 0.0
                result = predict(visslice, dpatch, **kwargs)
                svis.data['vis'][rows] += result.data['vis']

    if not isinstance(vis, Visibility):
        svis = convert_visibility_to_blockvisibility(svis)

    return svis
Exemple #7
0
def create_gaintable_from_screen(vis,
                                 sc,
                                 screen,
                                 height=3e5,
                                 vis_slices=None,
                                 scale=1.0,
                                 **kwargs):
    """ Create gaintables from a screen calculated using ARatmospy

    :param vis:
    :param sc: Sky components for which pierce points are needed
    :param screen:
    :param height: Height (in m) of screen above telescope e.g. 3e5
    :param scale: Multiply the screen by this factor
    :return:
    """
    assert isinstance(vis, BlockVisibility)

    station_locations = vis.configuration.xyz

    nant = station_locations.shape[0]
    t2r = numpy.pi / 43200.0
    gaintables = [
        create_gaintable_from_blockvisibility(vis, **kwargs) for i in sc
    ]

    # The time in the Visibility is hour angle in seconds!
    for iha, rows in enumerate(vis_timeslice_iter(vis, vis_slices=vis_slices)):
        v = create_visibility_from_rows(vis, rows)
        ha = numpy.average(v.time)
        number_bad = 0
        number_good = 0

        for icomp, comp in enumerate(sc):
            pp = find_pierce_points(station_locations,
                                    (comp.direction.ra.rad + t2r * ha) * u.rad,
                                    comp.direction.dec,
                                    height=height,
                                    phasecentre=vis.phasecentre)
            scr = numpy.zeros([nant])
            for ant in range(nant):
                pp0 = pp[ant][0:2]
                worldloc = [pp0[0], pp0[1], ha, 1e8]
                try:
                    pixloc = screen.wcs.wcs_world2pix([worldloc],
                                                      0)[0].astype('int')
                    scr[ant] = scale * screen.data[pixloc[3], pixloc[2],
                                                   pixloc[1], pixloc[0]]
                    number_good += 1
                except:
                    number_bad += 1
                    scr[ant] = 0.0

            gaintables[icomp].gain[iha, :, :, :] = numpy.exp(
                1j * scr[:, numpy.newaxis, numpy.newaxis, numpy.newaxis])
            gaintables[icomp].phasecentre = comp.direction

        if number_bad > 0:
            log.warning(
                "create_gaintable_from_screen: %d pierce points are inside the screen image"
                % (number_good))
            log.warning(
                "create_gaintable_from_screen: %d pierce points are outside the screen image"
                % (number_bad))

    return gaintables
def simulate_gaintable_from_voltage_patterns(vis,
                                             sc,
                                             vp_list,
                                             vp_coeffs,
                                             vis_slices=None,
                                             order=3,
                                             use_radec=False,
                                             **kwargs):
    """ Create gaintables for a set of zernikes

    :param vis:
    :param sc: Sky components for which pierce points are needed
    :param vp: List of Voltage patterns in AZELGEO frame
    :param vp_coeffs: Fractional contribution [nants, nvp]
    :param order: order of spline (default is 3)
    :return:
    """

    ntimes, nant = vis.vis.shape[0:2]
    vp_coeffs = numpy.array(vp_coeffs)
    gaintables = [
        create_gaintable_from_blockvisibility(vis, **kwargs) for i in sc
    ]

    if not use_radec:
        assert isinstance(vis, BlockVisibility)
        assert vis.configuration.mount[
            0] == 'azel', "Mount %s not supported yet" % vis.configuration.mount[
                0]

        # The time in the Visibility is hour angle in seconds!
        number_bad = 0
        number_good = 0

        # Cache the splines, one per voltage pattern
        real_splines = list()
        imag_splines = list()
        for ivp, vp in enumerate(vp_list):
            assert vp.wcs.wcs.ctype[0] == 'AZELGEO long', vp.wcs.wcs.ctype[0]
            assert vp.wcs.wcs.ctype[1] == 'AZELGEO lati', vp.wcs.wcs.ctype[1]

            nchan, npol, ny, nx = vp.data.shape
            real_splines.append(
                RectBivariateSpline(range(ny),
                                    range(nx),
                                    vp.data[0, 0, ...].real,
                                    kx=order,
                                    ky=order))
            imag_splines.append(
                RectBivariateSpline(range(ny),
                                    range(nx),
                                    vp.data[0, 0, ...].imag,
                                    kx=order,
                                    ky=order))

        latitude = vis.configuration.location.lat.rad

        r2d = 180.0 / numpy.pi
        s2r = numpy.pi / 43200.0
        # For each hourangle, we need to calculate the location of a component
        # in AZELGEO. With that we can then look up the relevant gain from the
        # voltage pattern
        for iha, rows in enumerate(
                vis_timeslice_iter(vis, vis_slices=vis_slices)):
            v = create_visibility_from_rows(vis, rows)
            ha = numpy.average(v.time)
            har = s2r * ha

            # Calculate the az el for this hourangle and the phasecentre declination
            azimuth_centre, elevation_centre = hadec_to_azel(
                har, vis.phasecentre.dec.rad, latitude)

            for icomp, comp in enumerate(sc):
                antgain = numpy.zeros([nant], dtype='complex')
                # Calculate the location of the component in AZELGEO, then add the pointing offset
                # for each antenna
                hacomp = comp.direction.ra.rad - vis.phasecentre.ra.rad + har
                deccomp = comp.direction.dec.rad
                azimuth_comp, elevation_comp = hadec_to_azel(
                    hacomp, deccomp, latitude)

                for ant in range(nant):
                    for ivp, vp in enumerate(vp_list):
                        nchan, npol, ny, nx = vp.data.shape
                        wcs_azel = vp.wcs.deepcopy()

                        az_comp = azimuth_centre * r2d
                        el_comp = elevation_centre * r2d

                        # We use WCS sensible coordinate handling by labelling the axes misleadingly
                        wcs_azel.wcs.crval[0] = az_comp
                        wcs_azel.wcs.crval[1] = el_comp
                        wcs_azel.wcs.ctype[0] = 'RA---SIN'
                        wcs_azel.wcs.ctype[1] = 'DEC--SIN'

                        worldloc = [
                            azimuth_comp * r2d, elevation_comp * r2d,
                            vp.wcs.wcs.crval[2], vp.wcs.wcs.crval[3]
                        ]
                        try:
                            pixloc = wcs_azel.sub(2).wcs_world2pix(
                                [worldloc[:2]], 1)[0]
                            assert pixloc[0] > 2
                            assert pixloc[0] < nx - 3
                            assert pixloc[1] > 2
                            assert pixloc[1] < ny - 3
                            gain = real_splines[ivp].ev(pixloc[1], pixloc[0]) \
                                   + 1j * imag_splines[ivp](pixloc[1], pixloc[0])
                            antgain[ant] += vp_coeffs[ant, ivp] * gain
                            number_good += 1
                        except:
                            number_bad += 1
                            antgain[ant] = 0.0

                    antgain[ant] = 1.0 / antgain[ant]

                gaintables[icomp].gain[iha, :, :, :] = antgain[:,
                                                               numpy.newaxis,
                                                               numpy.newaxis,
                                                               numpy.newaxis]
                gaintables[icomp].phasecentre = comp.direction
    else:
        assert isinstance(vis, BlockVisibility)
        number_bad = 0
        number_good = 0

        # Cache the splines, one per voltage pattern
        real_splines = list()
        imag_splines = list()
        for ivp, vp in enumerate(vp_list):

            nchan, npol, ny, nx = vp.data.shape
            real_splines.append(
                RectBivariateSpline(range(ny),
                                    range(nx),
                                    vp.data[0, 0, ...].real,
                                    kx=order,
                                    ky=order))
            imag_splines.append(
                RectBivariateSpline(range(ny),
                                    range(nx),
                                    vp.data[0, 0, ...].imag,
                                    kx=order,
                                    ky=order))

        for iha, rows in enumerate(
                vis_timeslice_iter(vis, vis_slices=vis_slices)):

            # The time in the Visibility is hour angle in seconds!
            r2d = 180.0 / numpy.pi
            # For each hourangle, we need to calculate the location of a component
            # in AZELGEO. With that we can then look up the relevant gain from the
            # voltage pattern
            v = create_visibility_from_rows(vis, rows)
            ha = numpy.average(v.time)

            for icomp, comp in enumerate(sc):
                antgain = numpy.zeros([nant], dtype='complex')
                antwt = numpy.zeros([nant])
                ra_comp = comp.direction.ra.rad
                dec_comp = comp.direction.dec.rad
                for ant in range(nant):
                    for ivp, vp in enumerate(vp_list):

                        assert vp.wcs.wcs.ctype[
                            0] == 'RA---SIN', vp.wcs.wcs.ctype[0]
                        assert vp.wcs.wcs.ctype[
                            1] == 'DEC--SIN', vp.wcs.wcs.ctype[1]

                        worldloc = [
                            ra_comp * r2d, dec_comp * r2d, vp.wcs.wcs.crval[2],
                            vp.wcs.wcs.crval[3]
                        ]
                        nchan, npol, ny, nx = vp.data.shape

                        try:
                            pixloc = vp.wcs.sub(2).wcs_world2pix(
                                [worldloc[:2]], 1)[0]
                            assert pixloc[0] > 2
                            assert pixloc[0] < nx - 3
                            assert pixloc[1] > 2
                            assert pixloc[1] < ny - 3
                            gain = real_splines[ivp].ev(pixloc[1], pixloc[0]) \
                                   + 1j * imag_splines[ivp](pixloc[1], pixloc[0])
                            antgain[ant] += vp_coeffs[ant, ivp] * gain
                            antwt[ant] = 1.0
                            number_good += 1
                        except:
                            number_bad += 1
                            antgain[ant] = 1e15
                            antwt[ant] = 0.0

                        antgain[ant] = 1.0 / antgain[ant]

                    gaintables[icomp].gain[
                        iha, :, :, :] = antgain[:, numpy.newaxis,
                                                numpy.newaxis, numpy.newaxis]
                    gaintables[icomp].weight[
                        iha, :, :, :] = antwt[:, numpy.newaxis, numpy.newaxis,
                                              numpy.newaxis]
                    gaintables[icomp].phasecentre = comp.direction

    if number_bad > 0:
        log.warning(
            "simulate_gaintable_from_voltage_patterns: %d points are inside the voltage pattern image"
            % (number_good))
        log.warning(
            "simulate_gaintable_from_voltage_patterns: %d points are outside the voltage pattern image"
            % (number_bad))

    return gaintables
Exemple #9
0
def create_gaintable_from_pointingtable(vis,
                                        sc,
                                        pt,
                                        vp,
                                        vis_slices=None,
                                        scale=1.0,
                                        order=3,
                                        **kwargs):
    """ Create gaintables from a pointing table

    :param vis:
    :param sc: Sky components for which pierce points are needed
    :param pt: Pointing table
    :param vp: Voltage pattern
    :param scale: Multiply the screen by this factor
    :param order: order of spline (default is 3)
    :return:
    """
    assert isinstance(vis, BlockVisibility)

    nant = vis.vis.shape[1]
    gaintables = [
        create_gaintable_from_blockvisibility(vis, **kwargs) for i in sc
    ]

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

    real_spline = RectBivariateSpline(range(ny),
                                      range(nx),
                                      vp.data[0, 0, ...].real,
                                      kx=order,
                                      ky=order)
    imag_spline = RectBivariateSpline(range(ny),
                                      range(nx),
                                      vp.data[0, 0, ...].imag,
                                      kx=order,
                                      ky=order)

    # The time in the Visibility is hour angle in seconds!
    for iha, rows in enumerate(vis_timeslice_iter(vis, vis_slices=vis_slices)):
        v = create_visibility_from_rows(vis, rows)
        ha = numpy.average(v.time)
        pt_rows = (pt.time == ha)
        pointing_ha = pt.pointing[pt_rows]
        number_bad = 0
        number_good = 0

        r2d = 180.0 / numpy.pi
        for icomp, comp in enumerate(sc):
            antgain = numpy.zeros([nant], dtype='complex')
            for ant in range(nant):
                worldloc = [
                    float(
                        (comp.direction.ra.rad + pointing_ha[0, ant, 0, 0, 0])
                        * r2d),
                    float(
                        (comp.direction.dec.rad + pointing_ha[0, ant, 0, 0, 1])
                        * r2d), vp.wcs.wcs.crval[2], vp.wcs.wcs.crval[3]
                ]
                try:
                    pixloc = vp.wcs.wcs_world2pix([worldloc], 0)[0][0:2]
                    gain = real_spline.ev(
                        pixloc[1],
                        pixloc[0]) + 1j * imag_spline(pixloc[1], pixloc[0])
                    antgain[ant] = 1.0 / (scale * gain)
                    number_good += 1
                except:
                    number_bad += 1
                    antgain[ant] = 0.0

            gaintables[icomp].gain[iha, :, :, :] = antgain[:, numpy.newaxis,
                                                           numpy.newaxis,
                                                           numpy.newaxis]
            gaintables[icomp].phasecentre = comp.direction

        if number_bad > 0:
            log.warning(
                "create_gaintable_from_pointingtable: %d points are inside the voltage pattern image"
                % (number_good))
            log.warning(
                "create_gaintable_from_pointingtable: %d points are outside the voltage pattern image"
                % (number_bad))

    return gaintables