예제 #1
0
    def test_invert(self):

        uvfitsfile = arl_path("data/vis/ASKAP_example.fits")

        nchan_ave = 32
        nchan = 192
        for schan in range(0, nchan, nchan_ave):
            max_chan = min(nchan, schan + nchan_ave)
            bv = create_blockvisibility_from_uvfits(uvfitsfile,
                                                    range(schan, max_chan))[0]
            vis = convert_blockvisibility_to_visibility(bv)
            from processing_components.visibility.operations import convert_visibility_to_stokesI
            vis = convert_visibility_to_stokesI(vis)
            model = create_image_from_visibility(
                vis,
                npixel=256,
                polarisation_frame=PolarisationFrame('stokesI'))
            dirty, sumwt = invert_2d(vis, model, context='2d')
            assert (numpy.max(numpy.abs(dirty.data))) > 0.0
            assert dirty.shape == (nchan_ave, 1, 256, 256)
            import matplotlib.pyplot as plt
            from processing_components.image.operations import show_image
            show_image(dirty)
            plt.show()
            if self.persist:
                export_image_to_fits(
                    dirty, '%s/test_visibility_uvfits_dirty.fits' % self.dir)
    def test_skymodel_solve_fixed(self):
        self.actualSetup(ntimes=1, doiso=True, fixed=True)
        calskymodel, residual_vis = calskymodel_solve(self.vis,
                                                      self.skymodels,
                                                      niter=30,
                                                      gain=0.25)

        # Check that the components are unchanged
        calskymodel_skycomponents = list()
        for sm in [csm[0] for csm in calskymodel]:
            for comp in sm.components:
                calskymodel_skycomponents.append(comp)

        recovered_components = find_skycomponent_matches(
            calskymodel_skycomponents, self.components, 1e-5)
        for p in recovered_components:
            assert numpy.abs(calskymodel_skycomponents[p[0]].flux[0, 0] -
                             self.components[p[1]].flux[0, 0]) < 1e-15
            assert calskymodel_skycomponents[p[0]].direction.separation(
                self.components[p[1]].direction).rad < 1e-15

        residual_vis = convert_blockvisibility_to_visibility(residual_vis)
        residual_vis, _, _ = weight_visibility(residual_vis, self.beam)
        dirty, sumwt = invert_function(residual_vis, self.beam, context='2d')
        export_image_to_fits(
            dirty, "%s/test_skymodel-final-iso-residual.fits" % self.dir)

        qa = qa_image(dirty)
        assert qa.data['rms'] < 3.4e-3, qa
예제 #3
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
예제 #4
0
 def test_convert_decoalesce_zero(self):
     cvis = convert_blockvisibility_to_visibility(self.blockvis)
     assert numpy.min(cvis.frequency) == numpy.min(self.frequency)
     assert numpy.min(cvis.frequency) > 0.0
     dvis = decoalesce_visibility(cvis)
     assert dvis.nvis == self.blockvis.nvis
     dvis = decoalesce_visibility(cvis)
     assert dvis.nvis == self.blockvis.nvis
예제 #5
0
 def get_wf(bv):
     v = convert_blockvisibility_to_visibility(bv)
     return advise_wide_field(v,
                              guard_band_image=6.0,
                              delA=0.02,
                              facets=facets,
                              wprojection_planes=wprojection_planes,
                              oversampling_synthesised_beam=4.0)
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
예제 #7
0
 def test_convert_blockvisibility(self):
     self.vis = create_blockvisibility(
         self.lowcore,
         self.times,
         self.frequency,
         phasecentre=self.phasecentre,
         weight=1.0,
         channel_bandwidth=self.channel_bandwidth)
     vis = convert_blockvisibility_to_visibility(self.vis)
     assert vis.nvis == len(vis.time)
     assert numpy.unique(vis.time).size == self.vis.time.size  # pylint: disable=no-member
예제 #8
0
 def test_convert_weight(self):
     cvis = convert_blockvisibility_to_visibility(self.blockvis)
     model = create_image_from_visibility(vis=cvis, npixel=256, cellsize=0.001, phasecentre=self.phasecentre,
                                          polarisation_frame=PolarisationFrame('stokesI'))
     cvis = weight_visibility(cvis, model)
     assert numpy.mean(cvis.data['imaging_weight']) < 1.0
     assert numpy.std(cvis.data['imaging_weight']) > 0.0
     dvis = decoalesce_visibility(cvis)
     assert numpy.mean(dvis.data['imaging_weight']) < 1.0
     assert numpy.std(dvis.data['imaging_weight']) > 0.0
     assert dvis.nvis == self.blockvis.nvis
예제 #9
0
    def actualSetUp(self, freqwin=1, block=True, dopol=False):

        self.npixel = 512
        self.low = create_named_configuration('LOWBD2', rmax=750.0)
        self.freqwin = freqwin
        self.vis = list()
        self.ntimes = 5
        self.times = numpy.linspace(-3.0, +3.0, self.ntimes) * numpy.pi / 12.0

        if dopol:
            self.vis_pol = PolarisationFrame('linear')
            self.image_pol = PolarisationFrame('stokesIQUV')
            f = numpy.array([100.0, 20.0, -10.0, 1.0])
        else:
            self.vis_pol = PolarisationFrame('stokesI')
            self.image_pol = PolarisationFrame('stokesI')
            f = numpy.array([100.0])

        if freqwin > 1:
            self.frequency = numpy.linspace(0.8e8, 1.2e8, self.freqwin)
            self.channelwidth = numpy.array(
                freqwin * [self.frequency[1] - self.frequency[0]])
            flux = numpy.array(
                [f * numpy.power(freq / 1e8, -0.7) for freq in self.frequency])
        else:
            self.frequency = numpy.array([1e8])
            self.channelwidth = numpy.array([1e6])
            flux = numpy.array([f])

        self.phasecentre = SkyCoord(ra=+180.0 * u.deg,
                                    dec=-60.0 * u.deg,
                                    frame='icrs',
                                    equinox='J2000')
        self.bvis = ingest_unittest_visibility(self.low,
                                               self.frequency,
                                               self.channelwidth,
                                               self.times,
                                               self.vis_pol,
                                               self.phasecentre,
                                               block=block)

        self.vis = convert_blockvisibility_to_visibility(self.bvis)

        self.model = create_unittest_model(self.vis,
                                           self.image_pol,
                                           npixel=self.npixel,
                                           nchan=freqwin)

        self.components = create_unittest_components(self.model, flux)

        self.model = insert_skycomponent(self.model, self.components)

        self.bvis = predict_skycomponent_visibility(self.bvis, self.components)
예제 #10
0
 def test_convert_weight(self):
     cvis = convert_blockvisibility_to_visibility(self.blockvis)
     cvis.data['imaging_weight'] = 10.0
     model = create_image_from_visibility(
         vis=cvis,
         npixel=256,
         cellsize=0.001,
         phasecentre=self.phasecentre,
         polarisation_frame=PolarisationFrame('stokesI'))
     cvis = weight_visibility(cvis, model)
     dvis = decoalesce_visibility(cvis, overwrite=True)
     assert numpy.max(dvis.data['imaging_weight'] - 10.0) < 1e-7
     assert dvis.nvis == self.blockvis.nvis
예제 #11
0
def create_visibility_from_uvfits(fitsname, channum=None, ack=False, antnum=None):
    """ Minimal UVFITS to BlockVisibility converter

    Creates a list of BlockVisibility's, split by field and spectral window

    :param fitsname: File name of UVFITS file
    :param channum: range of channels e.g. range(17,32), default is None meaning all
    :param antnum: the number of antenna
    :return:
    """
    from processing_components.visibility.coalesce import convert_blockvisibility_to_visibility
    return [convert_blockvisibility_to_visibility(v)
            for v in create_blockvisibility_from_uvfits(fitsname=fitsname, channum=channum, ack=ack, antnum=antnum)]
def calskymodel_fit_skymodel(vis, calskymodel, gain=0.1, **kwargs):
    """Fit a single skymodel to a visibility

    :param evis: Expected vis for this ssm
    :param calskymodel: scm element being fit i.e. (skymodel, gaintable) tuple
    :param gain: Gain in step
    :param kwargs:
    :return: skymodel
    """
    if calskymodel[0].fixed:
        return calskymodel[0]
    else:
        cvis = convert_blockvisibility_to_visibility(vis)
        return solve_skymodel(cvis, calskymodel[0], **kwargs)
예제 #13
0
def create_visibility_from_ms(msname, channum=None, ack=False):
    """ Minimal MS to BlockVisibility converter

    The MS format is much more general than the ARL BlockVisibility so we cut many corners. This requires casacore to be
    installed. If not an exception ModuleNotFoundError is raised.

    Creates a list of BlockVisibility's, split by field and spectral window

    :param msname: File name of MS
    :param channum: range of channels e.g. range(17,32), default is None meaning all
    :return:
    """
    from processing_components.visibility.coalesce import convert_blockvisibility_to_visibility
    return [convert_blockvisibility_to_visibility(v)
            for v in create_blockvisibility_from_ms(msname=msname, channum=channum, ack=ack)]
    def test_skymodel_solve_noiso(self):
        self.actualSetup(ntimes=1, doiso=False)
        calskymodel, residual_vis = calskymodel_solve(self.vis,
                                                      self.skymodels,
                                                      niter=30,
                                                      gain=0.25)

        residual_vis = convert_blockvisibility_to_visibility(residual_vis)
        residual_vis, _, _ = weight_visibility(residual_vis, self.beam)
        dirty, sumwt = invert_function(residual_vis, self.beam, context='2d')
        export_image_to_fits(
            dirty, "%s/test_skymodel-final-noiso-residual.fits" % self.dir)

        qa = qa_image(dirty)
        assert qa.data['rms'] < 3.8e-3, qa
예제 #15
0
 def test_predict_sky_components_coalesce(self):
     sc = create_low_test_skycomponents_from_gleam(flux_limit=10.0,
                                                   polarisation_frame=PolarisationFrame("stokesI"),
                                                   frequency=self.frequency, kind='cubic',
                                                   phasecentre=SkyCoord("17h20m31s", "-00d58m45s"),
                                                   radius=0.1)
     self.config = create_named_configuration('LOWBD2-CORE')
     self.phasecentre = SkyCoord("17h20m31s", "-00d58m45s")
     sampling_time = 3.76
     self.times = numpy.arange(0.0, + 300 * sampling_time, sampling_time)
     self.vis = create_blockvisibility(self.config, self.times, self.frequency, phasecentre=self.phasecentre,
                                       weight=1.0, polarisation_frame=PolarisationFrame('stokesI'),
                                       channel_bandwidth=self.channel_bandwidth)
     self.vis = predict_skycomponent_visibility(self.vis, sc)
     cvt = convert_blockvisibility_to_visibility(self.vis)
     assert cvt.cindex is not None
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
 def test_modelpartition_solve_arlexecute(self):
     
     self.actualSetup(doiso=True)
     
     self.skymodel_list = [arlexecute.execute(SkyModel, nout=1)(components=[cm])
                           for cm in self.components]
     
     modelpartition_list = solve_modelpartition_arlexecute(self.vis, skymodel_list=self.skymodel_list, niter=30,
                                                           gain=0.25)
     skymodel, residual_vis = arlexecute.compute(modelpartition_list, sync=True)
     
     residual_vis = convert_blockvisibility_to_visibility(residual_vis)
     residual_vis, _, _ = weight_visibility(residual_vis, self.beam)
     dirty, sumwt = invert_arlexecute(residual_vis, self.beam, context='2d')
     export_image_to_fits(dirty, "%s/test_modelpartition-%s-final-iso-residual.fits" % (self.dir, arlexecute.type()))
     
     qa = qa_image(dirty)
     assert qa.data['rms'] < 3.2e-3, qa
예제 #18
0
def create_visibility_from_ms(msname, channum=None, start_chan=None, end_chan=None,  ack=False):
    """ Minimal MS to BlockVisibility converter

    The MS format is much more general than the ARL BlockVisibility so we cut many corners. This requires casacore to be
    installed. If not an exception ModuleNotFoundError is raised.

    Creates a list of BlockVisibility's, split by field and spectral window

    Reading of a subset of channels is possible using either start_chan and end_chan or channnum. Using start_chan
    and end_chan is preferred since it only reads the channels required. Channum is more flexible and can be used to
    read a random list of channels.
    
    :param msname: File name of MS
    :param channum: range of channels e.g. range(17,32), default is None meaning all
    :param start_chan: Starting channel to read
    :param end_chan: End channel to read
    :return:
    """
    from processing_components.visibility.coalesce import convert_blockvisibility_to_visibility
    return [convert_blockvisibility_to_visibility(v)
            for v in create_blockvisibility_from_ms(msname=msname, channum=channum,
                                                    start_chan=start_chan, end_chan=end_chan, ack=ack)]
예제 #19
0
    def test_export_ms(self):
        if run_ms_tests == False:
            return

        msoutfile = arl_path("data/vis/Test_output.ms")

        from astropy.coordinates import SkyCoord
        from astropy import units as u

        from wrappers.serial.image.operations import show_image, export_image_to_fits
        from wrappers.serial.simulation.configurations import create_named_configuration
        from wrappers.serial.simulation.testing_support import create_test_image
        from wrappers.serial.imaging.base import create_image_from_visibility
        from wrappers.serial.imaging.base import advise_wide_field

        from workflows.serial.imaging.imaging_serial import invert_list_serial_workflow, predict_list_serial_workflow

        from data_models.polarisation import PolarisationFrame

        lowr3 = create_named_configuration('LOWBD2', rmax=750.0)

        times = numpy.zeros([1])
        frequency = numpy.array([1e8])
        channelbandwidth = numpy.array([1e6])
        phasecentre = SkyCoord(ra=+15.0 * u.deg, dec=-45.0 * u.deg, frame='icrs', equinox='J2000')

        bvis = create_blockvisibility(lowr3, times, frequency, phasecentre=phasecentre,
                                               weight=1.0, polarisation_frame=PolarisationFrame('stokesI'),
                                               channel_bandwidth=channelbandwidth)

        vt = convert_blockvisibility_to_visibility(bvis)

        advice = advise_wide_field(vt, guard_band_image=3.0, delA=0.1, facets=1, wprojection_planes=1,
                                   oversampling_synthesised_beam=4.0)
        cellsize = advice['cellsize']


        m31image = create_test_image(frequency=frequency, cellsize=cellsize)
        nchan, npol, ny, nx = m31image.data.shape
        m31image.wcs.wcs.crval[0] = vt.phasecentre.ra.deg
        m31image.wcs.wcs.crval[1] = vt.phasecentre.dec.deg
        m31image.wcs.wcs.crpix[0] = float(nx // 2)
        m31image.wcs.wcs.crpix[1] = float(ny // 2)
        vt = predict_list_serial_workflow([vt], [m31image], context='2d')[0]
        # uvdist = numpy.sqrt(vt.data['uvw'][:, 0] ** 2 + vt.data['uvw'][:, 1] ** 2)
        #
        # model = create_image_from_visibility(vt, cellsize=cellsize, npixel=512)
        # dirty, sumwt = invert_list_serial_workflow([vt], [model], context='2d')[0]
        # psf, sumwt = invert_list_serial_workflow([vt], [model], context='2d', dopsf=True)[0]
        #
        # show_image(dirty)
        # print("Max, min in dirty image = %.6f, %.6f, sumwt = %f" % (dirty.data.max(), dirty.data.min(), sumwt))
        #
        # print("Max, min in PSF         = %.6f, %.6f, sumwt = %f" % (psf.data.max(), psf.data.min(), sumwt))
        # results_dir="/Users/f.wang"
        # export_image_to_fits(dirty, '%s/imaging_dirty.fits' % (results_dir))
        # export_image_to_fits(psf, '%s/imaging_psf.fits' % (results_dir))

        v = convert_visibility_to_blockvisibility(vt)
        vis_list=[]
        vis_list.append(v)
        export_blockvisility_to_ms(msoutfile, vis_list,source_name='M31')
예제 #20
0
def create_blockvisibility_iterator(
        config: Configuration,
        times: numpy.array,
        frequency: numpy.array,
        channel_bandwidth,
        phasecentre: SkyCoord,
        weight: float = 1,
        polarisation_frame=PolarisationFrame('stokesI'),
        integration_time=1.0,
        number_integrations=1,
        predict=predict_2d,
        model=None,
        components=None,
        phase_error=0.0,
        amplitude_error=0.0,
        sleep=0.0,
        **kwargs):
    """ Create a sequence of Visibilities and optionally predicting and coalescing

    This is useful mainly for performing large simulations. Do something like::
    
        vis_iter = create_blockvisibility_iterator(config, times, frequency, channel_bandwidth, phasecentre=phasecentre,
                                              weight=1.0, integration_time=30.0, number_integrations=3)

        for i, vis in enumerate(vis_iter):
        if i == 0:
            fullvis = vis
        else:
            fullvis = append_visibility(fullvis, vis)


    :param config: Configuration of antennas
    :param times: hour angles in radians
    :param frequency: frequencies (Hz] Shape [nchan]
    :param weight: weight of a single sample
    :param phasecentre: phasecentre of observation
    :param npol: Number of polarizations
    :param integration_time: Integration time ('auto' or value in s)
    :param number_integrations: Number of integrations to be created at each time.
    :param model: Model image to be inserted
    :param components: Components to be inserted
    :param sleep_time: Time to sleep between yields
    :return: Visibility

    """
    for time in times:
        actualtimes = time + numpy.arange(
            0, number_integrations) * integration_time * numpy.pi / 43200.0
        bvis = create_blockvisibility(config,
                                      actualtimes,
                                      frequency=frequency,
                                      phasecentre=phasecentre,
                                      weight=weight,
                                      polarisation_frame=polarisation_frame,
                                      integration_time=integration_time,
                                      channel_bandwidth=channel_bandwidth)

        if model is not None:
            vis = convert_blockvisibility_to_visibility(bvis)
            vis = predict(vis, model, **kwargs)
            bvis = convert_visibility_to_blockvisibility(vis)

        if components is not None:
            vis = predict_skycomponent_visibility(bvis, components)

        # Add phase errors
        if phase_error > 0.0 or amplitude_error > 0.0:
            gt = create_gaintable_from_blockvisibility(bvis)
            gt = simulate_gaintable(gt=gt,
                                    phase_error=phase_error,
                                    amplitude_error=amplitude_error)
            bvis = apply_gaintable(bvis, gt)

        import time
        time.sleep(sleep)

        yield bvis
예제 #21
0
 def to_vis(v):
     if isinstance(v, BlockVisibility):
         av = convert_blockvisibility_to_visibility(v)
         return av
     else:
         return v
    def actualSetUp(self,
                    freqwin=1,
                    block=True,
                    dospectral=True,
                    dopol=False,
                    zerow=False,
                    do_shift=False):

        self.npixel = 512
        self.low = create_named_configuration('LOWBD2', rmax=750.0)
        self.freqwin = freqwin
        self.blockvis = list()
        self.ntimes = 5
        self.times = numpy.linspace(-3.0, +3.0, self.ntimes) * numpy.pi / 12.0

        if freqwin > 1:
            self.frequency = numpy.linspace(0.99e8, 1.01e8, self.freqwin)
            self.channelwidth = numpy.array(
                freqwin * [self.frequency[1] - self.frequency[0]])
        else:
            self.frequency = numpy.array([1e8])
            self.channelwidth = numpy.array([1e6])

        if dopol:
            self.blockvis_pol = PolarisationFrame('linear')
            self.image_pol = PolarisationFrame('stokesIQUV')
            f = numpy.array([100.0, 20.0, -10.0, 1.0])
        else:
            self.blockvis_pol = PolarisationFrame('stokesI')
            self.image_pol = PolarisationFrame('stokesI')
            f = numpy.array([100.0])

        if dospectral:
            flux = numpy.array(
                [f * numpy.power(freq / 1e8, -0.7) for freq in self.frequency])
        else:
            flux = numpy.array([f])

        self.phasecentre = SkyCoord(ra=+180.0 * u.deg,
                                    dec=-45.0 * u.deg,
                                    frame='icrs',
                                    equinox='J2000')
        self.blockvis = ingest_unittest_visibility(self.low,
                                                   self.frequency,
                                                   self.channelwidth,
                                                   self.times,
                                                   self.blockvis_pol,
                                                   self.phasecentre,
                                                   block=block,
                                                   zerow=zerow)

        self.vis = convert_blockvisibility_to_visibility(self.blockvis)

        self.model = create_unittest_model(self.vis,
                                           self.image_pol,
                                           npixel=self.npixel,
                                           nchan=freqwin)

        self.components = create_unittest_components(self.model, flux)

        self.model = insert_skycomponent(self.model, self.components)

        self.blockvis = predict_skycomponent_visibility(
            self.blockvis, self.components)

        # Calculate the model convolved with a Gaussian.

        self.cmodel = smooth_image(self.model)
        if self.persist:
            export_image_to_fits(self.model,
                                 '%s/test_imaging_ng_model.fits' % self.dir)
        if self.persist:
            export_image_to_fits(self.cmodel,
                                 '%s/test_imaging_ng_cmodel.fits' % self.dir)
    def actualSetup(self,
                    vnchan=1,
                    doiso=True,
                    ntimes=5,
                    flux_limit=2.0,
                    zerow=True,
                    fixed=False):

        nfreqwin = vnchan
        rmax = 300.0
        npixel = 512
        cellsize = 0.001
        frequency = numpy.linspace(0.8e8, 1.2e8, nfreqwin)
        if nfreqwin > 1:
            channel_bandwidth = numpy.array(nfreqwin *
                                            [frequency[1] - frequency[0]])
        else:
            channel_bandwidth = [0.4e8]
        times = numpy.linspace(-numpy.pi / 3.0, numpy.pi / 3.0, ntimes)

        phasecentre = SkyCoord(ra=-60.0 * u.deg,
                               dec=-60.0 * u.deg,
                               frame='icrs',
                               equinox='J2000')

        lowcore = create_named_configuration('LOWBD2', rmax=rmax)

        block_vis = create_blockvisibility(
            lowcore,
            times,
            frequency=frequency,
            channel_bandwidth=channel_bandwidth,
            weight=1.0,
            phasecentre=phasecentre,
            polarisation_frame=PolarisationFrame("stokesI"),
            zerow=zerow)

        block_vis.data['uvw'][..., 2] = 0.0
        self.beam = create_image_from_visibility(
            block_vis,
            npixel=npixel,
            frequency=[numpy.average(frequency)],
            nchan=nfreqwin,
            channel_bandwidth=[numpy.sum(channel_bandwidth)],
            cellsize=cellsize,
            phasecentre=phasecentre)

        self.components = create_low_test_skycomponents_from_gleam(
            flux_limit=flux_limit,
            phasecentre=phasecentre,
            frequency=frequency,
            polarisation_frame=PolarisationFrame('stokesI'),
            radius=npixel * cellsize)
        self.beam = create_low_test_beam(self.beam)
        self.components = apply_beam_to_skycomponent(self.components,
                                                     self.beam,
                                                     flux_limit=flux_limit)

        self.vis = copy_visibility(block_vis, zero=True)
        gt = create_gaintable_from_blockvisibility(block_vis, timeslice='auto')
        for i, sc in enumerate(self.components):
            if sc.flux[0, 0] > 10:
                sc.flux[...] /= 10.0
            component_vis = copy_visibility(block_vis, zero=True)
            gt = simulate_gaintable(gt,
                                    amplitude_error=0.0,
                                    phase_error=0.1,
                                    seed=None)
            component_vis = predict_skycomponent_visibility(component_vis, sc)
            component_vis = apply_gaintable(component_vis, gt)
            self.vis.data['vis'][...] += component_vis.data['vis'][...]

        # Do an isoplanatic selfcal
        self.model_vis = copy_visibility(self.vis, zero=True)
        self.model_vis = predict_skycomponent_visibility(
            self.model_vis, self.components)
        if doiso:
            gt = solve_gaintable(self.vis,
                                 self.model_vis,
                                 phase_only=True,
                                 timeslice='auto')
            self.vis = apply_gaintable(self.vis, gt, inverse=True)

        self.model_vis = convert_blockvisibility_to_visibility(self.model_vis)
        self.model_vis, _, _ = weight_visibility(self.model_vis, self.beam)
        self.dirty_model, sumwt = invert_function(self.model_vis,
                                                  self.beam,
                                                  context='2d')
        export_image_to_fits(self.dirty_model,
                             "%s/test_skymodel-model_dirty.fits" % self.dir)

        lvis = convert_blockvisibility_to_visibility(self.vis)
        lvis, _, _ = weight_visibility(lvis, self.beam)
        dirty, sumwt = invert_function(lvis, self.beam, context='2d')
        if doiso:
            export_image_to_fits(
                dirty, "%s/test_skymodel-initial-iso-residual.fits" % self.dir)
        else:
            export_image_to_fits(
                dirty,
                "%s/test_skymodel-initial-noiso-residual.fits" % self.dir)

        self.skymodels = [
            SkyModel(components=[cm], fixed=fixed) for cm in self.components
        ]
def ical_serial(block_vis: BlockVisibility,
                model: Image,
                components=None,
                context='2d',
                controls=None,
                **kwargs):
    """ Post observation image, deconvolve, and self-calibrate

    :param vis:
    :param model: Model image
    :param components: Initial components
    :param context: Imaging context
    :param controls: calibration controls dictionary
    :return: model, residual, restored
    """
    nmajor = get_parameter(kwargs, 'nmajor', 5)
    log.info("ical_serial: Performing %d major cycles" % nmajor)

    do_selfcal = get_parameter(kwargs, "do_selfcal", False)

    if controls is None:
        controls = create_calibration_controls(**kwargs)

    # The model is added to each major cycle and then the visibilities are
    # calculated from the full model
    vis = convert_blockvisibility_to_visibility(block_vis)
    block_vispred = copy_visibility(block_vis, zero=True)
    vispred = convert_blockvisibility_to_visibility(block_vispred)
    vispred.data['vis'][...] = 0.0
    visres = copy_visibility(vispred)

    vispred = predict_serial(vispred, model, context=context, **kwargs)

    if components is not None:
        vispred = predict_skycomponent_visibility(vispred, components)

    if do_selfcal:
        vis, gaintables = calibrate_function(vis,
                                             vispred,
                                             'TGB',
                                             controls,
                                             iteration=-1)

    visres.data['vis'] = vis.data['vis'] - vispred.data['vis']
    dirty, sumwt = invert_serial(visres, model, context=context, **kwargs)
    log.info("Maximum in residual image is %.6f" %
             (numpy.max(numpy.abs(dirty.data))))

    psf, sumwt = invert_serial(visres,
                               model,
                               dopsf=True,
                               context=context,
                               **kwargs)

    thresh = get_parameter(kwargs, "threshold", 0.0)

    for i in range(nmajor):
        log.info("ical_serial: Start of major cycle %d of %d" % (i, nmajor))
        cc, res = deconvolve_cube(dirty, psf, **kwargs)
        model.data += cc.data
        vispred.data['vis'][...] = 0.0
        vispred = predict_serial(vispred, model, context=context, **kwargs)
        if do_selfcal:
            vis, gaintables = calibrate_function(vis,
                                                 vispred,
                                                 'TGB',
                                                 controls,
                                                 iteration=i)
        visres.data['vis'] = vis.data['vis'] - vispred.data['vis']

        dirty, sumwt = invert_serial(visres, model, context=context, **kwargs)
        log.info("Maximum in residual image is %s" %
                 (numpy.max(numpy.abs(dirty.data))))
        if numpy.abs(dirty.data).max() < 1.1 * thresh:
            log.info("ical_serial: Reached stopping threshold %.6f Jy" %
                     thresh)
            break
        log.info("ical_serial: End of major cycle")

    log.info("ical_serial: End of major cycles")
    restored = restore_cube(model, psf, dirty, **kwargs)

    return model, dirty, restored