In [ ]:
import numpy as np
import logging
import os
import astropy.units as u
import astropy.constants as const
import fastimgproto.imager as imager
import fastimgproto.visibility as visibility
from astropy.coordinates import Angle, SkyCoord, AltAz, EarthLocation
from astropy.time import Time
from fastimgproto.gridder.conv_funcs import GaussianSinc
from fastimgproto.skymodel.helpers import SkyRegion, SkySource
from fastimgproto.sourcefind.image import SourceFindImage
from fastimgproto.telescope.readymade import Meerkat
In [ ]:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
%matplotlib inline
# Plot image pixels in cartesian ordering (i.e. y-positive == upwards):
plt.rcParams['image.origin'] = 'lower'
# Make plots bigger
plt.rcParams['figure.figsize'] = 10, 10
In [ ]:
telescope = Meerkat()
In [ ]:
pointing_centre = SkyCoord(0 * u.deg, -30 * u.deg)
obs_central_frequency = 3. * u.GHz
wavelength = const.c / obs_central_frequency
transit_time = telescope.next_transit(pointing_centre.ra,
start_time=Time('2017-01-01'))
Choose the observation times / sampling regime
In [ ]:
nstep=10
obs_times = transit_time + np.linspace(-1, 1, nstep) * u.hr
print("Generating UVW-baselines for {} timesteps".format(nstep))
uvw_m = telescope.uvw_tracking_skycoord(pointing_centre, obs_times)
# From here on we use UVW as multiples of wavelength, lambda:
uvw_lambda = (uvw_m / wavelength).to(u.dimensionless_unscaled).value
Steady sources - one at pointing centre, one at a small offset:
In [ ]:
# Additional source to North-East of pointing centre
extra_src_position = SkyCoord(ra=pointing_centre.ra + 0.01 * u.deg,
dec=pointing_centre.dec + 0.01 * u.deg, )
steady_sources = [
SkySource(pointing_centre, flux=1 * u.Jy),
SkySource(extra_src_position, flux=0.4 * u.Jy),
]
And a transient source
In [ ]:
transient_posn = SkyCoord(
ra=pointing_centre.ra - 0.05 * u.deg,
dec=pointing_centre.dec - 0.05 * u.deg)
transient_sources = [
SkySource(position=transient_posn, flux=0.5 * u.Jy),
]
In [ ]:
model_sources = steady_sources
In [ ]:
data_sources = steady_sources
# data_sources = steady_sources + transient_sources
# Simulate some jitter (positional offsets) due to ionospheric effects (or pointing-errors or whatever)
# (ra, dec)
jitter = (0.5*u.arcsec, -0.5*u.arcsec)
jitter_sources = []
for src in data_sources:
jitter_src = SkySource(position=SkyCoord(ra = src.position.ra + jitter[0],
dec= src.position.dec+jitter[1]),
flux = src.flux
)
jitter_sources.append(jitter_src)
In [ ]:
data_sources
In [ ]:
jitter_sources
In [ ]:
model_vis = visibility.visibilities_for_source_list(
pointing_centre,
source_list = model_sources,
uvw = uvw_lambda)
In [ ]:
# Simulate incoming data; includes transient sources, noise:
baseline_noise_level = 0.1 * u.Jy
data_vis = visibility.visibilities_for_source_list(
pointing_centre,
# source_list = data_sources,
source_list = jitter_sources,
uvw = uvw_lambda)
data_vis = visibility.add_gaussian_noise(baseline_noise_level, data_vis)
residual_vis = data_vis - model_vis
In [ ]:
image_size=1024 * u.pixel
cell_size=1 * u.arcsecond
In [ ]:
kernel_support = 3
kernel_func = GaussianSinc(trunc=kernel_support)
In [ ]:
image, beam = imager.image_visibilities(
# model_vis,
# data_vis,
residual_vis,
uvw_lambda,
image_size=image_size,
cell_size=cell_size,
kernel_func=kernel_func,
kernel_support=kernel_support,
kernel_exact=True,
kernel_oversampling=None
)
image = np.real(image)
beam = np.real(beam)
In [ ]:
# %matplotlib notebook
%matplotlib inline
fig, axes = plt.subplots(ncols=2, figsize=(12,8))
clim = (-0.1, 0.7)
# xlim = (250,750)
xlim = (450,550)
# xlim = (550,800)
ylim = xlim
img_ax, bm_ax = axes
im_plot = img_ax.imshow(image,clim=clim)
bm_ax.imshow(beam,clim=clim)
img_ax.set_xlim(*xlim)
img_ax.set_ylim(*ylim)
img_ax.set_title('image')
x_range = xlim[1]-xlim[0]
y_range = ylim[1]-ylim[0]
beam_xlim = ( beam.shape[1]/2 - x_range/2, beam.shape[1]/2 + x_range/2)
beam_ylim = ( beam.shape[0]/2 - y_range/2, beam.shape[0]/2 + y_range/2)
bm_ax.set_xlim(beam_xlim)
bm_ax.set_ylim(beam_ylim)
bm_ax.set_title('beam (matched zoom)')
fig.subplots_adjust(right=0.8)
cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
fig.colorbar(im_plot, cax=cbar_ax)
beam_xlim, beam_ylim
Export the image-data to a FITS-file for closer inspection:
In [ ]:
import astropy.io.fits as fits
hdu = fits.PrimaryHDU(image)
# hdu.writeto('image.fits')
In [ ]:
from fastimgproto.sourcefind.image import SourceFindImage
In [ ]:
detection_n_sigma=30
analysis_n_sigma=15
sfimage = SourceFindImage(data=np.real(image),
detection_n_sigma=detection_n_sigma,
analysis_n_sigma=analysis_n_sigma,
)
In [ ]:
sfimage.islands
In [ ]:
src = sfimage.islands[0]
In [ ]:
fig, ax1 = plt.subplots(1,1)
ax1.imshow(image)
half_width = 75
xlims = int(src.xbar)-half_width, int(src.xbar)+half_width
ylims = int(src.ybar)-half_width, int(src.ybar)+half_width
ax1.set_xlim(xlims)
ax1.set_ylim(ylims)
for src in sfimage.islands:
ax1.axvline(src.xbar, ls=':')
ax1.axhline(src.ybar, ls=':')