Пример #1
0
def copy_skycomponent(sc):
    """Copy a sky component of Iterable of skycomponents
    
    :param sc:
    :return:
    """
    single = not isinstance(sc, collections.abc.Iterable)
    
    if single:
        return Skycomponent(
            direction=sc.direction,
            frequency=sc.frequency,
            name=sc.name,
            flux=sc.flux,
            shape=sc.shape,
            params=sc.params,
            polarisation_frame=sc.polarisation_frame)
    else:
        return [Skycomponent(
            direction=s.direction,
            frequency=s.frequency,
            name=s.name,
            flux=s.flux,
            shape=s.shape,
            params=s.params,
            polarisation_frame=s.polarisation_frame) for s in sc]
Пример #2
0
    def setUp(self):
        from rascil.data_models.parameters import rascil_path
        self.dir = rascil_path('test_results/')

        self.midcore = create_named_configuration('MID', rmax=3000.0)
        self.times = (numpy.pi / 43200.0) * numpy.arange(0.0, 300.0, 100.0)
        self.frequency = numpy.linspace(1.0e9, 1.1e9, 3)
        self.channel_bandwidth = numpy.array([1e7, 1e7, 1e7])
        # Define the component and give it some spectral behaviour
        f = numpy.array([100.0, 20.0, -10.0, 1.0])
        self.flux = numpy.array([f, 0.8 * f, 0.6 * f])

        # The phase centre is absolute and the component is specified relative (for now).
        # This means that the component should end up at the position phasecentre+compredirection
        self.phasecentre = SkyCoord(ra=+180.0 * u.deg,
                                    dec=-35.0 * u.deg,
                                    frame='icrs',
                                    equinox='J2000')
        self.compabsdirection = SkyCoord(ra=+181.0 * u.deg,
                                         dec=-35.0 * u.deg,
                                         frame='icrs',
                                         equinox='J2000')
        self.comp = Skycomponent(direction=self.compabsdirection,
                                 frequency=self.frequency,
                                 flux=self.flux)
Пример #3
0
    def setUp(self):
        self.lowcore = create_named_configuration('LOWBD2-CORE')
        self.times = (numpy.pi / 43200.0) * numpy.arange(0.0, 300.0, 30.0)
        self.frequency = numpy.linspace(1.0e8, 1.1e8, 3)
        self.channel_bandwidth = numpy.array([1e7, 1e7, 1e7])
        # Define the component and give it some spectral behaviour
        f = numpy.array([100.0, 20.0, -10.0, 1.0])
        self.flux = numpy.array([f, 0.8 * f, 0.6 * f])
        self.polarisation_frame = PolarisationFrame("linear")

        # The phase centre is absolute and the component is specified relative (for now).
        # This means that the component should end up at the position phasecentre+compredirection
        self.phasecentre = SkyCoord(ra=+180.0 * u.deg,
                                    dec=-35.0 * u.deg,
                                    frame='icrs',
                                    equinox='J2000')
        self.compabsdirection = SkyCoord(ra=+181.0 * u.deg,
                                         dec=-35.0 * u.deg,
                                         frame='icrs',
                                         equinox='J2000')
        pcof = self.phasecentre.skyoffset_frame()
        self.compreldirection = self.compabsdirection.transform_to(pcof)
        self.comp = Skycomponent(direction=self.compreldirection,
                                 frequency=self.frequency,
                                 flux=self.flux)
    def test_fit_visibility(self):
        # Sum the visibilities in the correct_visibility direction. This is limited by numerical precision
        methods = [
            'CG', 'BFGS', 'Powell', 'trust-ncg', 'trust-exact', 'trust-krylov'
        ]
        for method in methods:
            self.actualSetup()
            self.vis = create_visibility(
                self.lowcore,
                self.times,
                self.frequency,
                channel_bandwidth=self.channel_bandwidth,
                phasecentre=self.phasecentre,
                weight=1.0,
                polarisation_frame=PolarisationFrame("stokesI"))
            self.vismodel = dft_skycomponent_visibility(self.vis, self.comp)
            initial_comp = Skycomponent(
                direction=self.comp_start_direction,
                frequency=self.frequency,
                flux=2.0 * self.flux,
                polarisation_frame=PolarisationFrame("stokesI"))

            sc, res = fit_visibility(self.vismodel,
                                     initial_comp,
                                     niter=200,
                                     tol=1e-5,
                                     method=method,
                                     verbose=False)
            assert sc.direction.separation(self.comp_actual_direction).to('rad').value < 1e-6, \
                sc.direction.separation(self.comp_actual_direction).to('rad')
    def test_phase_rotation_stokesi(self):
       # Define the component and give it some spectral behaviour
        f = numpy.array([100.0])
        self.flux = numpy.array([f, 0.8 * f, 0.6 * f])
    
        # The phase centre is absolute and the component is specified relative (for now).
        # This means that the component should end up at the position phasecentre+compredirection
        self.phasecentre = SkyCoord(ra=+180.0 * u.deg, dec=-35.0 * u.deg, frame='icrs', equinox='J2000')
        self.compabsdirection = SkyCoord(ra=+181.0 * u.deg, dec=-35.0 * u.deg, frame='icrs', equinox='J2000')
        pcof = self.phasecentre.skyoffset_frame()
        self.compreldirection = self.compabsdirection.transform_to(pcof)
        self.comp = Skycomponent(direction=self.compreldirection, frequency=self.frequency, flux=self.flux,
                                     polarisation_frame=PolarisationFrame("stokesI"))
    
        self.vis = create_visibility(self.lowcore, self.times, self.frequency,
                                     channel_bandwidth=self.channel_bandwidth,
                                     phasecentre=self.phasecentre, weight=1.0,
                                     polarisation_frame=PolarisationFrame("stokesI"))
        self.vismodel = predict_skycomponent_visibility(self.vis, self.comp)
        # Predict visibilities with new phase centre independently
        ha_diff = -(self.compabsdirection.ra - self.phasecentre.ra).to(u.rad).value
        vispred = create_visibility(self.lowcore, self.times + ha_diff, self.frequency,
                                    channel_bandwidth=self.channel_bandwidth,
                                    phasecentre=self.compabsdirection, weight=1.0,
                                    polarisation_frame=PolarisationFrame("stokesI"))
        vismodel2 = predict_skycomponent_visibility(vispred, self.comp)

        # Should yield the same results as rotation
        rotatedvis = phaserotate_visibility(self.vismodel, newphasecentre=self.compabsdirection, tangent=False)
        assert_allclose(rotatedvis.vis, vismodel2.vis, rtol=3e-6)
        assert_allclose(rotatedvis.uvw, vismodel2.uvw, rtol=3e-6)
    def actualSetup(self):
        self.lowcore = create_named_configuration('LOWBD2-CORE')
        self.times = (numpy.pi / 43200.0) * numpy.arange(0.0, 300.0, 30.0)
        self.times = [0.0]
        self.frequency = numpy.linspace(1.0e8, 1.1e8, 1)
        self.channel_bandwidth = numpy.array([1e7])
        # Define the component and give it some spectral behaviour
        f = numpy.array([100.0, 20.0, -10.0, 1.0])
        self.flux = numpy.array([f, 0.8 * f, 0.6 * f])

        f = numpy.array([100.0])
        self.flux = numpy.array([f])

        # The phase centre is absolute and the component is specified relative (for now).
        # This means that the component should end up at the position phasecentre+compredirection
        self.phasecentre = SkyCoord(ra=+180.0 * u.deg,
                                    dec=-35.0 * u.deg,
                                    frame='icrs',
                                    equinox='J2000')
        self.comp_actual_direction = SkyCoord(ra=+180.2 * u.deg,
                                              dec=-35.1 * u.deg,
                                              frame='icrs',
                                              equinox='J2000')
        self.comp_start_direction = SkyCoord(ra=+180.0 * u.deg,
                                             dec=-35.0 * u.deg,
                                             frame='icrs',
                                             equinox='J2000')
        self.comp = Skycomponent(
            direction=self.comp_actual_direction,
            frequency=self.frequency,
            flux=self.flux,
            polarisation_frame=PolarisationFrame("stokesI"))
Пример #7
0
    def test_create_vis_iter_with_model(self):
        model = create_test_image(canonical=True,
                                  cellsize=0.001,
                                  frequency=self.frequency,
                                  phasecentre=self.phasecentre)
        comp = Skycomponent(direction=self.phasecentre,
                            frequency=self.frequency,
                            flux=self.flux,
                            polarisation_frame=PolarisationFrame('stokesI'))
        vis_iter = create_blockvisibility_iterator(
            self.config,
            self.times,
            self.frequency,
            channel_bandwidth=self.channel_bandwidth,
            phasecentre=self.phasecentre,
            weight=1.0,
            polarisation_frame=PolarisationFrame('stokesI'),
            integration_time=30.0,
            number_integrations=3,
            model=model,
            components=comp)

        fullvis = None
        totalnvis = 0
        for i, bvis in enumerate(vis_iter):
            assert bvis.phasecentre == self.phasecentre
            assert bvis.nvis
            if i == 0:
                fullvis = bvis
                totalnvis = bvis.nvis
            else:
                fullvis = append_visibility(fullvis, bvis)
                totalnvis += bvis.nvis

        assert fullvis.nvis == totalnvis
    def test_simulate_gaintable_from_voltage_patterns(self):
        numpy.random.seed(18051955)
        offset_phasecentre = SkyCoord(ra=+15.0 * u.deg, dec=-44.58 * u.deg, frame='icrs', equinox='J2000')
        component = [Skycomponent(frequency=self.frequency, direction=offset_phasecentre,
                                  polarisation_frame=PolarisationFrame("stokesI"), flux=[[1.0]])]

        key_nolls = [3, 5, 6, 7]
        vp_list = list()
        vp_list.append(create_vp(self.model, 'MID_GAUSS', use_local=True))
        vp_coeffs = numpy.ones([self.nants, len(key_nolls)+1])
        for inoll, noll in enumerate(key_nolls):
            zernike = {'coeff': 1.0, 'noll': noll}
            vp_coeffs[:, inoll+1] = numpy.random.normal(0.0, 0.03, self.nants)
            vp_list.append(create_vp_generic_numeric(self.model, pointingcentre=None, diameter=15.0, blockage=0.0,
                                                      taper='gaussian',
                                                      edge=0.03162278, zernikes=[zernike], padding=2, use_local=True))

        gt = simulate_gaintable_from_zernikes(self.vis, component, vp_list, vp_coeffs)

        import matplotlib.pyplot as plt
        assert gt[0].gain.shape == (self.ntimes, self.nants, 1, 1, 1), gt[0].gain.shape
        
        plt.clf()
        for ant in range(self.nants):
            plt.plot(gt[0].time, 1.0 / numpy.real(gt[0].gain[:, ant, 0, 0, 0]), '.')
        plt.xlabel('Time (s)')
        plt.ylabel('Gain')
        plt.show(block=False)
Пример #9
0
    def test_simulate_gaintable_from_time_series(self):
        numpy.random.seed(18051955)
        offset_phasecentre = SkyCoord(ra=+15.0 * u.deg,
                                      dec=-44.58 * u.deg,
                                      frame='icrs',
                                      equinox='J2000')
        component = [
            Skycomponent(frequency=self.frequency,
                         direction=offset_phasecentre,
                         polarisation_frame=PolarisationFrame("stokesI"),
                         flux=[[1.0]])
        ]

        for type in ['wind']:

            pt = create_pointingtable_from_blockvisibility(self.vis)

            import matplotlib.pyplot as plt
            ant = 15
            plt.clf()
            plt.plot(pt.time, pt.nominal[:, ant, 0, 0, 0], '.')
            plt.plot(pt.time, pt.nominal[:, ant, 0, 0, 1], '.')
            plt.xlabel('Time (s)')
            plt.ylabel('Nominal (rad)')
            plt.title("Nominal pointing for %s" % (type))
            plt.show()

            for reference_pointing in [False, True]:
                pt = simulate_pointingtable_from_timeseries(
                    pt, type=type, reference_pointing=reference_pointing)

                import matplotlib.pyplot as plt
                ant = 15
                plt.clf()
                r2a = 180.0 * 3600.0 / numpy.pi
                plt.plot(pt.time, r2a * pt.pointing[:, ant, 0, 0, 0], '.')
                plt.plot(pt.time, r2a * pt.pointing[:, ant, 0, 0, 1], '.')
                plt.xlabel('Time (s)')
                plt.ylabel('Pointing (arcsec)')
                plt.title("Pointing for %s, reference pointing %s" %
                          (type, reference_pointing))
                plt.show()

                vp = create_vp(self.model, 'MID')
                gt = simulate_gaintable_from_pointingtable(
                    self.vis, component, pt, vp)
                assert gt[0].gain.shape == (self.ntimes, self.nants, 1, 1,
                                            1), gt[0].gain.shape

                plt.clf()
                plt.plot(gt[0].time,
                         1.0 / numpy.real(gt[0].gain[:, ant, 0, 0, 0]), '.')
                plt.xlabel('Time (s)')
                plt.ylabel('Gain')
                plt.title("Gain for %s, reference pointing %s" %
                          (type, reference_pointing))
                plt.show()
Пример #10
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
Пример #11
0
    def actualSetup(self,
                    sky_pol_frame='stokesIQUV',
                    data_pol_frame='linear',
                    f=None,
                    vnchan=1):
        self.lowcore = create_named_configuration('LOWBD2-CORE')
        self.times = (numpy.pi / 43200.0) * numpy.linspace(0.0, 30.0, 3)
        self.frequency = numpy.linspace(1.0e8, 1.1e8, vnchan)
        if vnchan > 1:
            self.channel_bandwidth = numpy.array(
                vnchan * [self.frequency[1] - self.frequency[0]])
        else:
            self.channel_bandwidth = numpy.array([2e7])

        if f is None:
            f = [100.0, 50.0, -10.0, 40.0]

        if sky_pol_frame == 'stokesI':
            f = [100.0]

        self.flux = numpy.outer(
            numpy.array(
                [numpy.power(freq / 1e8, -0.7) for freq in self.frequency]), f)

        # The phase centre is absolute and the component is specified relative (for now).
        # This means that the component should end up at the position phasecentre+compredirection
        self.phasecentre = SkyCoord(ra=+180.0 * u.deg,
                                    dec=-35.0 * u.deg,
                                    frame='icrs',
                                    equinox='J2000')
        self.compabsdirection = SkyCoord(ra=+181.0 * u.deg,
                                         dec=-35.0 * u.deg,
                                         frame='icrs',
                                         equinox='J2000')
        self.comp = Skycomponent(
            direction=self.compabsdirection,
            frequency=self.frequency,
            flux=self.flux,
            polarisation_frame=PolarisationFrame(sky_pol_frame))
        self.vis = create_blockvisibility(
            self.lowcore,
            self.times,
            self.frequency,
            phasecentre=self.phasecentre,
            channel_bandwidth=self.channel_bandwidth,
            weight=1.0,
            polarisation_frame=PolarisationFrame(data_pol_frame))
        self.vis = dft_skycomponent_visibility(self.vis, self.comp)
Пример #12
0
def create_skycomponent(direction: SkyCoord, flux: numpy.array, frequency: numpy.array, shape: str = 'Point',
                        polarisation_frame=PolarisationFrame("stokesIQUV"), params: dict = None, name: str = '') \
        -> Skycomponent:
    """ A single Skycomponent with direction, flux, shape, and params for the shape

    :param polarisation_frame:
    :param params:
    :param direction:
    :param flux:
    :param frequency:
    :param shape: 'Point' or 'Gaussian'
    :param name:
    :return: Skycomponent
    """
    return Skycomponent(direction=direction,
                        frequency=frequency,
                        name=name,
                        flux=numpy.array(flux),
                        shape=shape,
                        params=params,
                        polarisation_frame=polarisation_frame)
Пример #13
0
def convert_hdf_to_skycomponent(f):
    """ Convert HDF root to a SkyComponent

    :param f:
    :return:
    """
    assert f.attrs['RASCIL_data_model'] == "Skycomponent", "Not a Skycomponent"
    direction = convert_direction_from_string(f.attrs['direction'])
    frequency = numpy.array(f.attrs['frequency'])
    name = f.attrs['name']
    polarisation_frame = PolarisationFrame(f.attrs['polarisation_frame'])
    flux = f.attrs['flux']
    shape = f.attrs['shape']
    params = ast.literal_eval(f.attrs['params'])
    sc = Skycomponent(direction=direction,
                      frequency=frequency,
                      name=name,
                      flux=flux,
                      polarisation_frame=polarisation_frame,
                      shape=shape,
                      params=params)
    return sc
Пример #14
0
    def actualSetup(self, sky_pol_frame='stokesIQUV', data_pol_frame='linear'):
        self.lowcore = create_named_configuration('LOWBD2', rmax=100.0)
        self.times = (numpy.pi / 43200.0) * numpy.arange(0.0, 3000.0, 60.0)
        vnchan = 3
        self.frequency = numpy.linspace(1.0e8, 1.1e8, vnchan)
        self.channel_bandwidth = numpy.array(
            vnchan * [self.frequency[1] - self.frequency[0]])

        # Define the component and give it some spectral behaviour
        f = numpy.array([100.0, 20.0, -10.0, 1.0])
        self.flux = numpy.array([f, 0.8 * f, 0.6 * f])

        self.phasecentre = SkyCoord(ra=+180.0 * u.deg,
                                    dec=-35.0 * u.deg,
                                    frame='icrs',
                                    equinox='J2000')
        self.compabsdirection = SkyCoord(ra=+181.0 * u.deg,
                                         dec=-35.0 * u.deg,
                                         frame='icrs',
                                         equinox='J2000')
        if sky_pol_frame == 'stokesI':
            self.flux = self.flux[:, 0][:, numpy.newaxis]

        self.comp = Skycomponent(
            direction=self.compabsdirection,
            frequency=self.frequency,
            flux=self.flux,
            polarisation_frame=PolarisationFrame(sky_pol_frame))
        self.vis = create_blockvisibility(
            self.lowcore,
            self.times,
            self.frequency,
            phasecentre=self.phasecentre,
            channel_bandwidth=self.channel_bandwidth,
            weight=1.0,
            polarisation_frame=PolarisationFrame(data_pol_frame))
        self.vis = dft_skycomponent_visibility(self.vis, self.comp)
Пример #15
0
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
Пример #16
0
def create_simulation_components(context,
                                 phasecentre,
                                 frequency,
                                 pbtype,
                                 offset_dir,
                                 flux_limit,
                                 pbradius,
                                 pb_npixel,
                                 pb_cellsize,
                                 show=False):
    """ Construct components for simulation
    
    :param context:
    :param phasecentre:
    :param frequency:
    :param pbtype:
    :param offset_dir:
    :param flux_limit:
    :param pbradius:
    :param pb_npixel:
    :param pb_cellsize:
    :return:
    """

    HWHM_deg, null_az_deg, null_el_deg = find_pb_width_null(pbtype, frequency)

    dec = phasecentre.dec.deg
    ra = phasecentre.ra.deg

    if context == 'singlesource':
        log.info("create_simulation_components: Constructing single component")
        offset = [HWHM_deg * offset_dir[0], HWHM_deg * offset_dir[1]]
        log.info(
            "create_simulation_components: Offset from pointing centre = %.3f, %.3f deg"
            % (offset[0], offset[1]))

        # The point source is offset to approximately the halfpower point
        offset_direction = SkyCoord(
            ra=(ra + offset[0] / numpy.cos(numpy.pi * dec / 180.0)) *
            units.deg,
            dec=(dec + offset[1]) * units.deg,
            frame='icrs',
            equinox='J2000')

        original_components = [
            Skycomponent(flux=[[1.0]],
                         direction=offset_direction,
                         frequency=frequency,
                         polarisation_frame=PolarisationFrame('stokesI'))
        ]

    elif context == 'null':
        log.info(
            "create_simulation_components: Constructing single component at the null"
        )

        offset = [null_az_deg * offset_dir[0], null_el_deg * offset_dir[1]]
        HWHM = HWHM_deg * numpy.pi / 180.0

        log.info(
            "create_simulation_components: Offset from pointing centre = %.3f, %.3f deg"
            % (offset[0], offset[1]))

        # The point source is offset to approximately the null point
        offset_direction = SkyCoord(
            ra=(ra + offset[0] / numpy.cos(numpy.pi * dec / 180.0)) *
            units.deg,
            dec=(dec + offset[1]) * units.deg,
            frame='icrs',
            equinox='J2000')

        original_components = [
            Skycomponent(flux=[[1.0]],
                         direction=offset_direction,
                         frequency=frequency,
                         polarisation_frame=PolarisationFrame('stokesI'))
        ]

    else:
        offset = [0.0, 0.0]
        # Make a skymodel from S3
        max_flux = 0.0
        total_flux = 0.0
        log.info("create_simulation_components: Constructing s3sky components")
        from rascil.processing_components.simulation import create_test_skycomponents_from_s3

        original_components = create_test_skycomponents_from_s3(
            flux_limit=flux_limit / 100.0,
            phasecentre=phasecentre,
            polarisation_frame=PolarisationFrame("stokesI"),
            frequency=numpy.array(frequency),
            radius=pbradius)
        log.info(
            "create_simulation_components: %d components before application of primary beam"
            % (len(original_components)))

        pbmodel = create_image(npixel=pb_npixel,
                               cellsize=pb_cellsize,
                               phasecentre=phasecentre,
                               frequency=frequency,
                               polarisation_frame=PolarisationFrame("stokesI"))
        pb = create_pb(pbmodel,
                       "MID_GAUSS",
                       pointingcentre=phasecentre,
                       use_local=False)
        pb_feko = create_pb(pbmodel,
                            pbtype,
                            pointingcentre=phasecentre,
                            use_local=True)
        pb.data = pb_feko.data[:, 0, ...][:, numpy.newaxis, ...]
        pb_applied_components = [
            copy_skycomponent(c) for c in original_components
        ]
        pb_applied_components = apply_beam_to_skycomponent(
            pb_applied_components, pb)
        filtered_components = []
        for icomp, comp in enumerate(pb_applied_components):
            if comp.flux[0, 0] > flux_limit:
                total_flux += comp.flux[0, 0]
                if abs(comp.flux[0, 0]) > max_flux:
                    max_flux = abs(comp.flux[0, 0])
                filtered_components.append(original_components[icomp])
        log.info(
            "create_simulation_components: %d components > %.3f Jy after application of primary beam"
            % (len(filtered_components), flux_limit))
        log.info(
            "create_simulation_components: Strongest components is %g (Jy)" %
            max_flux)
        log.info(
            "create_simulation_components: Total flux in components is %g (Jy)"
            % total_flux)
        original_components = [
            copy_skycomponent(c) for c in filtered_components
        ]
        if show:
            plt.clf()
            show_image(pb, components=original_components)
            plt.show(block=False)

        log.info("create_simulation_components: Created %d components" %
                 len(original_components))
        # Primary beam points to the phasecentre
        offset_direction = SkyCoord(ra=ra * units.deg,
                                    dec=dec * units.deg,
                                    frame='icrs',
                                    equinox='J2000')

    return original_components, offset_direction
Пример #17
0
def find_skycomponents(im: Image,
                       fwhm=1.0,
                       threshold=1.0,
                       npixels=5) -> List[Skycomponent]:
    """ Find gaussian components in Image above a certain threshold as Skycomponent

    :param im: Image to be searched
    :param fwhm: Full width half maximum of gaussian in pixels
    :param threshold: Threshold for component detection. Default: 1 Jy.
    :param npixels: Number of connected pixels required
    :return: list of sky components
    """

    assert isinstance(im, Image)
    log.info("find_skycomponents: Finding components in Image by segmentation")

    # We use photutils segmentation - this first segments the image
    # into pieces that are thought to contain individual sources, then
    # identifies the concrete source properties. Having these two
    # steps makes it straightforward to extract polarisation and
    # spectral information.

    # Make filter kernel
    sigma = fwhm * gaussian_fwhm_to_sigma
    kernel = Gaussian2DKernel(sigma,
                              x_size=int(1.5 * fwhm),
                              y_size=int(1.5 * fwhm))
    kernel.normalize()

    # Segment the average over all channels of Stokes I
    image_sum = numpy.sum(im.data, axis=0)[0, ...] / float(im.shape[0])
    segments = segmentation.detect_sources(image_sum,
                                           threshold,
                                           npixels=npixels,
                                           filter_kernel=kernel)
    assert segments is not None, "Failed to find any components"

    log.info("find_skycomponents: Identified %d segments" % segments.nlabels)

    # Now compute source properties for all polarisations and frequencies
    comp_tbl = [[
        segmentation.source_properties(im.data[chan, pol],
                                       segments,
                                       filter_kernel=kernel,
                                       wcs=im.wcs.sub([1, 2])).to_table()
        for pol in [0]
    ] for chan in range(im.nchan)]

    def comp_prop(comp, prop_name):
        return [[comp_tbl[chan][pol][comp][prop_name] for pol in [0]]
                for chan in range(im.nchan)]

    # Generate components
    comps = []
    for segment in range(segments.nlabels):
        # Get flux and position. Astropy's quantities make this
        # unnecessarily complicated.
        flux = numpy.array(comp_prop(segment, "max_value"))
        # These values seem inconsistent with the xcentroid, and ycentroid values
        # ras = u.Quantity(list(map(u.Quantity,
        #         comp_prop(segment, "ra_icrs_centroid"))))
        # decs = u.Quantity(list(map(u.Quantity,
        #         comp_prop(segment, "dec_icrs_centroid"))))
        xs = u.Quantity(list(map(u.Quantity, comp_prop(segment, "xcentroid"))))
        ys = u.Quantity(list(map(u.Quantity, comp_prop(segment, "ycentroid"))))

        sc = pixel_to_skycoord(xs, ys, im.wcs, 0)
        ras = sc.ra
        decs = sc.dec

        # Remove NaNs from RA/DEC (happens if there is no flux in that
        # polarsiation/channel)
        # ras[numpy.isnan(ras)] = 0.0
        # decs[numpy.isnan(decs)] = 0.0

        # Determine "true" position by weighting
        flux_sum = numpy.sum(flux)
        ra = numpy.sum(flux * ras) / flux_sum
        dec = numpy.sum(flux * decs) / flux_sum
        xs = numpy.sum(flux * xs) / flux_sum
        ys = numpy.sum(flux * ys) / flux_sum

        point_flux = im.data[:, :,
                             numpy.round(ys.value).astype('int'),
                             numpy.round(xs.value).astype('int')]

        # Add component
        comps.append(
            Skycomponent(direction=SkyCoord(ra=ra, dec=dec),
                         frequency=im.frequency,
                         name="Segment %d" % segment,
                         flux=point_flux,
                         shape='Point',
                         polarisation_frame=im.polarisation_frame,
                         params={}))

    return comps
Пример #18
0
        print("Constructing single component")
        offset = [HWHM_deg, 0.0]
        if opposite:
            offset = [-1.0 * offset[0], -1.0 * offset[1]]
        print("Offset from pointing centre = %.3f, %.3f deg" %
              (offset[0], offset[1]))

        # The point source is offset to approximately the halfpower point
        offset_direction = SkyCoord(ra=(+15.0 + offset[0]) * u.deg,
                                    dec=(declination + offset[1]) * u.deg,
                                    frame='icrs',
                                    equinox='J2000')

        original_components = [
            Skycomponent(flux=[[1.0]],
                         direction=offset_direction,
                         frequency=frequency,
                         polarisation_frame=PolarisationFrame('stokesI'))
        ]
        print(original_components[0])

    else:
        # Make a skymodel from S3
        max_flux = 0.0
        total_flux = 0.0
        print("Constructing s3sky components")
        from rascil.processing_components.simulation.testing_support import create_test_skycomponents_from_s3

        original_components = create_test_skycomponents_from_s3(
            flux_limit=flux_limit / 100.0,
            phasecentre=phasecentre,
            polarisation_frame=PolarisationFrame("stokesI"),
def create_simulation_components(
        context,
        phasecentre,
        frequency,
        pbtype,
        offset_dir,
        flux_limit,
        pbradius,
        pb_npixel,
        pb_cellsize,
        show=False,
        fov=10,
        polarisation_frame=PolarisationFrame("stokesI"),
        filter_by_primary_beam=True,
        flux_max=10.0):
    """ Construct components for simulation
    
    :param context: singlesource or null or s3sky
    :param phasecentre: Centre of components
    :param frequency: Frequency
    :param pbtype: Type of primary beam
    :param offset_dir: Offset in ra, dec degrees
    :param flux_limit: Lower limit flux
    :param pbradius: Radius of components in radians
    :param pb_npixel: Number of pixels in the primary beam model
    :param pb_cellsize: Cellsize in primary beam model
    :param fov: FOV in degrees (used to select catalog)
    :param flux_max: Maximum flux in model before application of primary beam
    :param filter_by_primary_beam: Filter components by primary beam
    :param polarisation_frame:
    :param show:

    :return:
    """

    HWHM_deg, null_az_deg, null_el_deg = find_pb_width_null(pbtype, frequency)

    dec = phasecentre.dec.deg
    ra = phasecentre.ra.deg

    if context == 'singlesource':
        log.info("create_simulation_components: Constructing single component")
        offset = [HWHM_deg * offset_dir[0], HWHM_deg * offset_dir[1]]
        log.info(
            "create_simulation_components: Offset from pointing centre = %.3f, %.3f deg"
            % (offset[0], offset[1]))

        # The point source is offset to approximately the halfpower point
        odirection = SkyCoord(
            ra=(ra + offset[0] / numpy.cos(numpy.pi * dec / 180.0)) *
            units.deg,
            dec=(dec + offset[1]) * units.deg,
            frame='icrs',
            equinox='J2000')

        if polarisation_frame.type == "stokesIQUV":
            original_components = [
                Skycomponent(
                    flux=[[1.0, 0.0, 0.0, 0.0]],
                    direction=odirection,
                    frequency=frequency,
                    polarisation_frame=PolarisationFrame('stokesIQUV'))
            ]
        else:
            original_components = [
                Skycomponent(flux=[[1.0]],
                             direction=odirection,
                             frequency=frequency,
                             polarisation_frame=PolarisationFrame('stokesI'))
            ]

        offset_direction = odirection

    elif context == 'doublesource':

        original_components = []

        log.info(
            "create_simulation_components: Constructing double components")

        for sign_offset in [(-1, 0), (1, 0)]:
            offset = [HWHM_deg * sign_offset[0], HWHM_deg * sign_offset[1]]

            log.info(
                "create_simulation_components: Offset from pointing centre = %.3f, %.3f deg"
                % (offset[0], offset[1]))

            odirection = SkyCoord(
                ra=(ra + offset[0] / numpy.cos(numpy.pi * dec / 180.0)) *
                units.deg,
                dec=(dec + offset[1]) * units.deg,
                frame='icrs',
                equinox='J2000')
            if polarisation_frame.type == "stokesIQUV":
                original_components.append(
                    Skycomponent(
                        flux=[[1.0, 0.0, 0.0, 0.0]],
                        direction=odirection,
                        frequency=frequency,
                        polarisation_frame=PolarisationFrame('stokesIQUV')))
            else:
                original_components.append(
                    Skycomponent(
                        flux=[[1.0]],
                        direction=odirection,
                        frequency=frequency,
                        polarisation_frame=PolarisationFrame('stokesI')))

        for o in original_components:
            print(o)

        offset_direction = odirection

    elif context == 'null':
        log.info(
            "create_simulation_components: Constructing single component at the null"
        )

        offset = [null_az_deg * offset_dir[0], null_el_deg * offset_dir[1]]
        HWHM = HWHM_deg * numpy.pi / 180.0

        log.info(
            "create_simulation_components: Offset from pointing centre = %.3f, %.3f deg"
            % (offset[0], offset[1]))

        # The point source is offset to approximately the null point
        offset_direction = SkyCoord(
            ra=(ra + offset[0] / numpy.cos(numpy.pi * dec / 180.0)) *
            units.deg,
            dec=(dec + offset[1]) * units.deg,
            frame='icrs',
            equinox='J2000')

        if polarisation_frame.type == "stokesIQUV":
            original_components = [
                Skycomponent(
                    flux=[[1.0, 0.0, 0.0, 0.0]],
                    direction=offset_direction,
                    frequency=frequency,
                    polarisation_frame=PolarisationFrame('stokesIQUV'))
            ]
        else:
            original_components = [
                Skycomponent(flux=[[1.0]],
                             direction=offset_direction,
                             frequency=frequency,
                             polarisation_frame=PolarisationFrame('stokesI'))
            ]

    else:
        offset = [0.0, 0.0]
        # Make a skymodel from S3
        max_flux = 0.0
        total_flux = 0.0
        log.info("create_simulation_components: Constructing s3sky components")
        from rascil.processing_components.simulation import create_test_skycomponents_from_s3

        all_components = create_test_skycomponents_from_s3(
            flux_limit=flux_limit / 100.0,
            phasecentre=phasecentre,
            polarisation_frame=polarisation_frame,
            frequency=numpy.array(frequency),
            radius=pbradius,
            fov=fov)
        original_components = filter_skycomponents_by_flux(all_components,
                                                           flux_max=flux_max)
        log.info(
            "create_simulation_components: %d components before application of primary beam"
            % (len(original_components)))

        if filter_by_primary_beam:
            pbmodel = create_image(
                npixel=pb_npixel,
                cellsize=pb_cellsize,
                phasecentre=phasecentre,
                frequency=frequency,
                polarisation_frame=PolarisationFrame("stokesI"))
            stokesi_components = [
                copy_skycomponent(o) for o in original_components
            ]
            for s in stokesi_components:
                s.flux = numpy.array([[s.flux[0, 0]]])
                s.polarisation_frame = PolarisationFrame("stokesI")

            pb = create_pb(pbmodel,
                           "MID_GAUSS",
                           pointingcentre=phasecentre,
                           use_local=False)
            pb_applied_components = [
                copy_skycomponent(c) for c in stokesi_components
            ]
            pb_applied_components = apply_beam_to_skycomponent(
                pb_applied_components, pb)
            filtered_components = []
            for icomp, comp in enumerate(pb_applied_components):
                if comp.flux[0, 0] > flux_limit:
                    total_flux += comp.flux[0, 0]
                    if abs(comp.flux[0, 0]) > max_flux:
                        max_flux = abs(comp.flux[0, 0])
                    filtered_components.append(original_components[icomp])
            log.info(
                "create_simulation_components: %d components > %.3f Jy after filtering with primary beam"
                % (len(filtered_components), flux_limit))
            log.info(
                "create_simulation_components: Strongest components is %g (Jy)"
                % max_flux)
            log.info(
                "create_simulation_components: Total flux in components is %g (Jy)"
                % total_flux)
            original_components = [
                copy_skycomponent(c) for c in filtered_components
            ]
            if show:
                plt.clf()
                show_image(pb, components=original_components)
                plt.show(block=False)

        log.info("create_simulation_components: Created %d components" %
                 len(original_components))
        # Primary beam points to the phasecentre
        offset_direction = SkyCoord(ra=ra * units.deg,
                                    dec=dec * units.deg,
                                    frame='icrs',
                                    equinox='J2000')

    return original_components, offset_direction
Пример #20
0
def create_low_test_skycomponents_from_gleam(flux_limit=0.1, polarisation_frame=PolarisationFrame("stokesI"),
                                             frequency=numpy.array([1e8]), kind='cubic', phasecentre=None,
                                             radius=1.0) \
        -> List[Skycomponent]:
    """Create sky components from the GLEAM survey

    Stokes I is estimated from a cubic spline fit to the measured fluxes. The polarised flux is always zero.
    
    See http://www.mwatelescope.org/science/gleam-survey The catalog is available from Vizier.
    
    VIII/100   GaLactic and Extragalactic All-sky MWA survey  (Hurley-Walker+, 2016)

    GaLactic and Extragalactic All-sky Murchison Wide Field Array (GLEAM) survey. I: A low-frequency extragalactic
    catalogue. Hurley-Walker N., et al., Mon. Not. R. Astron. Soc., 464, 1146-1167 (2017), 2017MNRAS.464.1146H


    :param flux_limit: Only write components brighter than this (Jy)
    :param polarisation_frame: Polarisation frame (default PolarisationFrame("stokesI"))
    :param frequency: Frequencies at which the flux will be estimated
    :param kind: Kind of interpolation (see scipy.interpolate.interp1d) Default: linear
    :param phasecentre: Desired phase centre (SkyCoord) default None implies all sources
    :param radius: Radius of sources selected around phasecentre (default 1.0 rad)
    :return: List of Skycomponents
    """
    check_data_directory()

    fitsfile = rascil_path("data/models/GLEAM_EGC.fits")

    rad2deg = 180.0 / numpy.pi
    decmin = phasecentre.dec.to('deg').value - rad2deg * radius / 2.0
    decmax = phasecentre.dec.to('deg').value + rad2deg * radius / 2.0

    hdulist = fits.open(fitsfile, lazy_load_hdus=False)
    recs = hdulist[1].data[0].array

    fluxes = recs['peak_flux_wide']

    mask = fluxes > flux_limit
    filtered_recs = recs[mask]

    decs = filtered_recs['DEJ2000']
    mask = decs > decmin
    filtered_recs = filtered_recs[mask]

    decs = filtered_recs['DEJ2000']
    mask = decs < decmax
    filtered_recs = filtered_recs[mask]

    ras = filtered_recs['RAJ2000']
    decs = filtered_recs['DEJ2000']
    names = filtered_recs['Name']

    if polarisation_frame is None:
        polarisation_frame = PolarisationFrame("stokesI")

    npol = polarisation_frame.npol

    nchan = len(frequency)

    # For every source, we read all measured fluxes and interpolate to the
    # required frequencies
    gleam_freqs = numpy.array([
        76, 84, 92, 99, 107, 115, 122, 130, 143, 151, 158, 166, 174, 181, 189,
        197, 204, 212, 220, 227
    ])
    gleam_flux_freq = numpy.zeros([len(names), len(gleam_freqs)])
    for i, f in enumerate(gleam_freqs):
        gleam_flux_freq[:, i] = filtered_recs['int_flux_%03d' % (f)][:]

    skycomps = []

    directions = SkyCoord(ra=ras * u.deg, dec=decs * u.deg)
    if phasecentre is not None:
        separations = directions.separation(phasecentre).to('rad').value
    else:
        separations = numpy.zeros(len(names))

    for isource, name in enumerate(names):
        direction = directions[isource]
        if separations[isource] < radius:

            fint = interpolate.interp1d(gleam_freqs * 1.0e6,
                                        gleam_flux_freq[isource, :],
                                        kind=kind)
            flux = numpy.zeros([nchan, npol])
            flux[:, 0] = fint(frequency)
            if not numpy.isnan(flux).any():
                skycomps.append(
                    Skycomponent(direction=direction,
                                 flux=flux,
                                 frequency=frequency,
                                 name=name,
                                 shape='Point',
                                 polarisation_frame=polarisation_frame))

    log.info(
        'create_low_test_skycomponents_from_gleam: %d sources above flux limit %.3f'
        % (len(skycomps), flux_limit))

    hdulist.close()

    return skycomps
Пример #21
0
def create_test_skycomponents_from_s3(polarisation_frame=PolarisationFrame(
    "stokesI"),
                                      frequency=numpy.array([1e8]),
                                      channel_bandwidth=numpy.array([1e6]),
                                      phasecentre=None,
                                      fov=20,
                                      flux_limit=1e-3,
                                      radius=None):
    """Create test image from S3

    The input catalog was generated at http://s-cubed.physics.ox.ac.uk/s3_sex using the following query::
        Database: s3_sex
        SQL: select * from Galaxies where (pow(10,itot_151)*1000 > 1.0) and (right_ascension between -5 and 5) and (declination between -5 and 5);;

    Number of rows returned: 29966

    For frequencies < 610MHz, there are three tables to use::

        data/models/S3_151MHz_10deg.csv, use fov=10
        data/models/S3_151MHz_20deg.csv, use fov=20
        data/models/S3_151MHz_40deg.csv, use fov=40

    For frequencies > 610MHz, there are three tables:

        data/models/S3_1400MHz_1mJy_10deg.csv, use flux_limit>= 1e-3
        data/models/S3_1400MHz_100uJy_10deg.csv, use flux_limit < 1e-3
        data/models/S3_1400MHz_1mJy_18deg.csv, use flux_limit>= 1e-3
        data/models/S3_1400MHz_100uJy_18deg.csv, use flux_limit < 1e-3

    The component spectral index is calculated from the 610MHz and 151MHz or 1400MHz and 610MHz, and then calculated
    for the specified frequencies.

    If polarisation_frame is not stokesI then the image will a polarised axis but the values will be zero.

    :param polarisation_frame: Polarisation frame (default PolarisationFrame("stokesI"))
    :param frequency:
    :param channel_bandwidth: Channel width (Hz)
    :param phasecentre: phasecentre (SkyCoord)
    :param fov: fov 10 | 20 | 40
    :param flux_limit: Minimum flux (Jy)
    :return: Image
    """
    check_data_directory()

    ras = []
    decs = []
    fluxes = []
    names = []

    if phasecentre is None:
        phasecentre = SkyCoord(ra=+180.0 * u.deg,
                               dec=-60.0 * u.deg,
                               frame='icrs',
                               equinox='J2000')

    if polarisation_frame is None:
        polarisation_frame = PolarisationFrame("stokesI")

    if numpy.max(frequency) > 6.1E8:
        if fov > 10:
            fovstr = '18'
        else:
            fovstr = '10'
        if flux_limit >= 1e-3:
            csvfilename = rascil_data_path('models/S3_1400MHz_1mJy_%sdeg.csv' %
                                           fovstr)
        else:
            csvfilename = rascil_data_path(
                'models/S3_1400MHz_100uJy_%sdeg.csv' % fovstr)
        log.info(
            'create_test_skycomponents_from_s3: Reading S3-SEX sources from %s '
            % csvfilename)
    else:
        assert fov in [
            10, 20, 40
        ], "Field of view invalid: use one of %s" % ([10, 20, 40])
        csvfilename = rascil_data_path('models/S3_151MHz_%ddeg.csv' % (fov))
        log.info(
            'create_test_skycomponents_from_s3: Reading S3-SEX sources from %s '
            % csvfilename)

    skycomps = list()

    with open(csvfilename) as csvfile:
        readCSV = csv.reader(csvfile, delimiter=',')
        r = 0
        for row in readCSV:
            # Skip first row
            if r > 0:
                ra = float(row[4]) / numpy.cos(
                    phasecentre.dec.rad) + phasecentre.ra.deg
                dec = float(row[5]) + phasecentre.dec.deg
                if numpy.max(frequency) > 6.1E8:
                    alpha = (float(row[11]) - float(row[10])) / numpy.log10(
                        1400.0 / 610.0)
                    flux = numpy.power(10, float(row[10])) * numpy.power(
                        frequency / 1.4e9, alpha)
                else:
                    alpha = (float(row[10]) - float(row[9])) / numpy.log10(
                        610.0 / 151.0)
                    flux = numpy.power(10, float(row[9])) * numpy.power(
                        frequency / 1.51e8, alpha)
                if numpy.max(flux) > flux_limit:
                    ras.append(ra)
                    decs.append(dec)
                    if polarisation_frame == PolarisationFrame("stokesIQUV"):
                        polscale = numpy.array([1.0, 0.0, 0.0, 0.0])
                        fluxes.append(numpy.outer(flux, polscale))
                    else:
                        fluxes.append([[f] for f in flux])
                    names.append("S3_%s" % row[0])
            r += 1

    csvfile.close()

    assert len(fluxes) > 0, "No sources found above flux limit %s" % flux_limit

    directions = SkyCoord(ra=ras * u.deg, dec=decs * u.deg)
    if phasecentre is not None:
        separations = directions.separation(phasecentre).to('rad').value
    else:
        separations = numpy.zeros(len(names))

    for isource, name in enumerate(names):
        direction = directions[isource]
        if separations[isource] < radius:
            if not numpy.isnan(flux).any():
                skycomps.append(
                    Skycomponent(direction=direction,
                                 flux=fluxes[isource],
                                 frequency=frequency,
                                 name=names[isource],
                                 shape='Point',
                                 polarisation_frame=polarisation_frame))

    log.info(
        'create_test_skycomponents_from_s3: %d sources found above fluxlimit inside search radius'
        % len(skycomps))

    return skycomps