def predict_skycomponent_visibility( vis: Union[Visibility, BlockVisibility], sc: Union[Skycomponent, List[Skycomponent]] ) -> Union[Visibility, BlockVisibility]: """Predict the visibility from a Skycomponent, add to existing visibility, for Visibility or BlockVisibility :param vis: Visibility or BlockVisibility :param sc: Skycomponent or list of SkyComponents :return: Visibility or BlockVisibility """ if sc is None: return vis if not isinstance(sc, collections.Iterable): sc = [sc] if isinstance(vis, Visibility): _, im_nchan = list(get_frequency_map(vis, None)) for comp in sc: assert isinstance(comp, Skycomponent), comp assert_same_chan_pol(vis, comp) l, m, n = skycoord_to_lmn(comp.direction, vis.phasecentre) phasor = simulate_point(vis.uvw, l, m) comp = comp.flux[im_nchan, :] vis.data['vis'][...] += comp[:, :] * phasor[:, numpy.newaxis] elif isinstance(vis, BlockVisibility): ntimes, nant, _, nchan, npol = vis.vis.shape k = numpy.array(vis.frequency) / constants.c.to('m s^-1').value for comp in sc: # assert isinstance(comp, Skycomponent), comp assert_same_chan_pol(vis, comp) flux = comp.flux if comp.polarisation_frame != vis.polarisation_frame: flux = convert_pol_frame(flux, comp.polarisation_frame, vis.polarisation_frame) l, m, n = skycoord_to_lmn(comp.direction, vis.phasecentre) uvw = vis.uvw[..., numpy.newaxis] * k phasor = numpy.ones([ntimes, nant, nant, nchan, npol], dtype='complex') for chan in range(nchan): phasor[:, :, :, chan, :] = simulate_point(uvw[..., chan], l, m)[..., numpy.newaxis] vis.data['vis'][..., :, :] += flux[:, :] * phasor[..., :] return vis
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=0, 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 x >= 0 and x < nx and y >= 0 and 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
def apply_beam_to_skycomponent(sc: Union[Skycomponent, List[Skycomponent]], beam: Image, flux_limit=0.0) \ -> Union[Skycomponent, List[Skycomponent]]: """ Insert a Skycomponent into an image :param beam: :param sc: SkyComponent or list of SkyComponents :param flux_limit: flux limit on input :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))) newsc = [] total_flux = numpy.zeros([nchan, npol]) for comp in sc: assert comp.shape == 'Point', "Cannot handle shape %s" % comp.shape assert_same_chan_pol(beam, comp) pixloc = skycoord_to_pixel(comp.direction, beam.wcs, 1, 'wcs') if not numpy.isnan(pixloc).any(): x, y = int(round(float(pixloc[0]))), int(round(float(pixloc[1]))) if x >= 0 and x < nx and y >= 0 and y < ny: comp.flux[:, :] *= beam.data[:, :, y, x] # if comp.flux[:, :].any() > flux_limit: if comp.flux[0, 0] > flux_limit: 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
def insert_skycomponent(im: Image, sc: Union[Skycomponent, List[Skycomponent]], insert_method='Nearest', bandwidth=1.0, support=8) -> Image: """ Insert a Skycomponent into an image :param im: :param sc: SkyComponent or list of SkyComponents :param insert_method: '' | 'Sinc' | 'Lanczos' :param bandwidth: Fractional of uv plane to optimise over (1.0) :param support: Support of kernel (7) :return: image """ assert isinstance(im, Image) support = int(support / bandwidth) nchan, npol, ny, nx = im.data.shape if not isinstance(sc, collections.Iterable): sc = [sc] log.debug("insert_skycomponent: Using insert method %s" % insert_method) image_frequency = im.frequency ras = [comp.direction.ra.radian for comp in sc] decs = [comp.direction.dec.radian for comp in sc] skycoords = SkyCoord(ras * u.rad, decs * u.rad, frame='icrs') pixlocs = skycoord_to_pixel(skycoords, im.wcs, origin=0, mode='wcs') for icomp, comp in enumerate(sc): assert comp.shape == 'Point', "Cannot handle shape %s" % comp.shape assert_same_chan_pol(im, comp) pixloc = (pixlocs[0][icomp], pixlocs[1][icomp]) flux = numpy.zeros([nchan, npol]) if comp.flux.shape[0] > 1: for pol in range(npol): fint = interpolate.interp1d(comp.frequency, comp.flux[:, pol], kind="cubic") flux[:, pol] = fint(image_frequency) else: flux = comp.flux if insert_method == "Lanczos": insert_array(im.data, pixloc[0], pixloc[1], flux, bandwidth, support, insert_function=insert_function_L) elif insert_method == "Sinc": insert_array(im.data, pixloc[0], pixloc[1], flux, bandwidth, support, insert_function=insert_function_sinc) elif insert_method == "PSWF": insert_array(im.data, pixloc[0], pixloc[1], flux, bandwidth, support, insert_function=insert_function_pswf) else: insert_method = 'Nearest' y, x = numpy.round(pixloc[1]).astype('int'), numpy.round(pixloc[0]).astype('int') if 0 <= x < nx and 0 <= y < ny: im.data[:, :, y, x] += flux[...] return im