def plot_grid(self, filename=None, show=False, plot_radii=[], xy_lim=None): if self.uv_grid is None: self.grid_uvw_coords() grid_size = self.uv_grid.shape[0] wavelength = const.c.value / self.freq_hz fov_rad = Imager.uv_cellsize_to_fov(self.grid_cell_size_m / wavelength, grid_size) extent = Imager.grid_extent_wavelengths(degrees(fov_rad), grid_size) extent = np.array(extent) * wavelength fig, ax = plt.subplots(figsize=(8, 8), ncols=1, nrows=1) fig.subplots_adjust(left=0.125, bottom=0.1, right=0.9, top=0.9, wspace=0.2, hspace=0.2) image = self.uv_grid.real options = dict(interpolation='nearest', cmap='gray_r', extent=extent, origin='lower') im = ax.imshow(image, norm=ImageNormalize(stretch=LogStretch()), **options) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="2%", pad=0.03) cbar = ax.figure.colorbar(im, cax=cax) cbar.set_label('baselines per pixel') cbar.ax.tick_params(labelsize='small') ticks = np.arange(5) * round(image.max() / 5) ticks = np.append(ticks, image.max()) cbar.set_ticks(ticks, update_ticks=True) for r in plot_radii: ax.add_artist(plt.Circle((0, 0), r, fill=False, color='r')) ax.set_xlabel('uu (m)') ax.set_ylabel('vv (m)') ax.grid(True) if xy_lim is not None: ax.set_xlim(-xy_lim, xy_lim) ax.set_ylim(-xy_lim, xy_lim) if filename is not None: label = '' if 'ska1_v5' in filename: label = 'SKA1 v5' if 'model' in filename: label = 'Model ' + str( re.search(r'\d+', os.path.basename(filename)).group()) ax.text(0.02, 0.95, label, weight='bold', transform=ax.transAxes) fig.savefig(filename) if show: plt.show() if filename is not None or show: plt.close(fig) else: return fig
def plot_grid(self, filename=None, show=False, plot_radii=[], x_lim=None, y_lim=None): if self.uv_grid is None: self.grid_uvw_coords() grid_size = self.uv_grid.shape[0] wavelength = const.c.value / self.freq_hz fov_rad = Imager.uv_cellsize_to_fov(self.grid_cell_size_m / wavelength, grid_size) extent = Imager.grid_extent_wavelengths(degrees(fov_rad), grid_size) extent = np.array(extent) * wavelength fig, ax = plt.subplots(figsize=(8, 8), ncols=1, nrows=1) fig.subplots_adjust(left=0.125, bottom=0.1, right=0.9, top=0.9, wspace=0.2, hspace=0.2) image = self.uv_grid.real options = dict(interpolation='nearest', cmap='gray_r', extent=extent, origin='lower') im = ax.imshow(image, norm=ImageNormalize(stretch=LogStretch()), **options) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="2%", pad=0.03) cbar = ax.figure.colorbar(im, cax=cax) cbar.set_label('baselines per pixel') cbar.ax.tick_params(labelsize='small') ticks = np.arange(5) * round(image.max() / 5) ticks = np.append(ticks, image.max()) cbar.set_ticks(ticks, update_ticks=True) for r in plot_radii: ax.add_artist(plt.Circle((0, 0), r, fill=False, color='r')) ax.set_xlabel('uu (m)') ax.set_ylabel('vv (m)') if not x_lim is None: ax.set_xlim(x_lim) if not y_lim is None: ax.set_ylim(y_lim) if filename is not None: fig.savefig(filename) if show: plt.show() if filename is not None or show: plt.close(fig) else: return fig
def eval_psf(self, im_size=None, fov_deg=None, plot2d=False, plot1d=True): if self.uu_m is None: self.gen_uvw_coords() # Evaluate grid size and fov if needed. if im_size is None: b_max = self.r_uv_m.max() grid_size = int(ceil(b_max / self.grid_cell_size_m)) * 2 + \ self.station_diameter_m if grid_size % 2 == 1: grid_size += 1 else: grid_size = im_size wavelength = const.c.value / self.freq_hz if fov_deg is None: cellsize_wavelengths = self.grid_cell_size_m / wavelength fov_rad = Imager.uv_cellsize_to_fov(cellsize_wavelengths, grid_size) fov_deg = degrees(fov_rad) else: fov_deg = fov_deg uu = self.uu_m / wavelength vv = self.vv_m / wavelength ww = self.ww_m / wavelength amp = np.ones_like(uu, dtype='c8') psf = Imager.make_image(uu, vv, ww, np.ones_like(uu, dtype='c8'), fov_deg, grid_size) extent = Imager.image_extent_lm(fov_deg, grid_size) self.psf = psf self.psf_fov_deg = fov_deg # --- Plotting ---- if plot2d: fig, ax = plt.subplots(figsize=(8, 8)) norm = SymLogNorm(linthresh=0.05, linscale=1.0, vmin=-0.05, vmax=0.5, clip=False) opts = dict(interpolation='nearest', origin='lower', cmap='gray_r', extent=extent, norm=norm) im = ax.imshow(psf, **opts) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.03) cbar = ax.figure.colorbar(im, cax=cax) cbar.ax.tick_params(labelsize='small') ax.set_xlabel('l') ax.set_ylabel('m') plt.savefig('psf.png') plt.show() plt.close(fig) if plot1d: l, m = Imager.image_pixels(self.psf_fov_deg, grid_size) r_lm = (l**2 + m**2)**0.5 r_lm = r_lm.flatten() idx_sorted = np.argsort(r_lm) r_lm = r_lm[idx_sorted] psf_1d = self.psf.flatten()[idx_sorted] psf_hwhm = (wavelength / (r_lm[-1] * 2.0)) / 2 fig, ax = plt.subplots(figsize=(8, 8)) ax.plot(r_lm, psf_1d, 'k.', ms=2, alpha=0.1) ax.set_xscale('log') ax.set_yscale('log') fig.savefig('TEST_psf1d.png') plt.close(fig) num_bins = 100 # FIXME(BM) make this a function arg psf_1d_mean = np.zeros(num_bins) psf_1d_abs_mean = np.zeros(num_bins) psf_1d_abs_max = np.zeros(num_bins) psf_1d_min = np.zeros(num_bins) psf_1d_max = np.zeros(num_bins) psf_1d_std = np.zeros(num_bins) bin_edges = np.linspace(r_lm[0], r_lm[-1], num_bins + 1) # bin_edges = np.logspace(log10(r_lm[1]), log10(r_lm[-1]), # num_bins + 1) psf_1d_bin_r = (bin_edges[1:] + bin_edges[:-1]) / 2 bin_idx = np.digitize(r_lm, bin_edges) for i in range(1, num_bins + 1): values = psf_1d[bin_idx == i] if values.size > 0: psf_1d_mean[i - 1] = np.mean(values) psf_1d_abs_mean[i - 1] = np.mean(np.abs(values)) psf_1d_abs_max[i - 1] = np.max(np.abs(values)) psf_1d_min[i - 1] = np.min(values) psf_1d_max[i - 1] = np.max(values) psf_1d_std[i - 1] = np.std(values) fig, ax = plt.subplots(figsize=(8, 8)) ax.plot(psf_1d_bin_r, psf_1d_abs_mean, '-', c='b', lw=1, label='abs mean') ax.plot(psf_1d_bin_r, psf_1d_abs_max, '-', c='r', lw=1, label='abs max') ax.plot(psf_1d_bin_r, psf_1d_std, '-', c='g', lw=1, label='std') # ax.set_ylim(-0.1, 0.5) # ax.set_xlim(0, psf_1d_bin_r[-1] / 2**0.5) # ax.set_xscale('log') ax.set_yscale('log') ax.set_ylim(1e-4, 1) ax.set_xlim(0, psf_1d_bin_r[-1] / 2**0.5) ax.set_xlabel('PSF radius (direction cosines)') # ax.set_ylabel('PSF amplitude') ax.set_title('Azimuthally averaged PSF (FoV: %.2f)' % fov_deg) ax.legend() plt.show() plt.close(fig)
def eval_psf(self, im_size=None, fov_deg=None, plot2d=False, plot1d=True, filename_root=None, num_bins=100): """Evaluate and plot the PSF.""" if self.uu_m is None: self.gen_uvw_coords() # Work out a usable grid size. if im_size is None: b_max = self.r_uv_m.max() grid_size = int(ceil(b_max / self.grid_cell_size_m)) * 2 + \ self.station_diameter_m if grid_size % 2 == 1: grid_size += 1 else: grid_size = im_size # Work out the FoV wavelength = const.c.value / self.freq_hz if fov_deg is None: cellsize_wavelengths = self.grid_cell_size_m / wavelength fov_rad = Imager.uv_cellsize_to_fov(cellsize_wavelengths, grid_size) fov_deg = degrees(fov_rad) else: fov_deg = fov_deg uu = self.uu_m / wavelength vv = self.vv_m / wavelength ww = self.ww_m / wavelength amp = np.ones_like(uu, dtype='c8') # _r = (uu**2 + vv**2)**0.5 * wavelength # amp[_r <= 1e3] = 0.0 psf = Imager.make_image(uu, vv, ww, amp, fov_deg, grid_size, weighting='Natural') extent = Imager.image_extent_lm(fov_deg, grid_size) self.psf = psf self.psf_fov_deg = fov_deg # --- Plotting ---- if plot2d: fig, ax = plt.subplots(figsize=(8, 8)) norm = SymLogNorm(linthresh=0.005, linscale=1.0, vmin=-0.005, vmax=1.0, clip=False) opts = dict(interpolation='nearest', origin='lower', cmap='inferno', extent=extent, norm=norm) # opts = dict(interpolation='nearest', origin='lower', cmap='gray_r', # extent=extent) im = ax.imshow(psf, **opts) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.03) cbar = ax.figure.colorbar(im, cax=cax) cbar.ax.tick_params(labelsize='small') ax.set_xlabel('l') ax.set_ylabel('m') if filename_root: label = '' if 'ska1_v5' in filename_root: label = 'SKA1 v5' if 'model' in filename_root: label = 'Model ' + str( re.search(r'\d+', os.path.basename(filename_root)).group()) ax.text(0.02, 0.95, label, color='white', weight='bold', transform=ax.transAxes) plt.savefig('%s_2d_%.1f.png' % (filename_root, fov_deg)) else: plt.show() plt.close(fig) if plot1d: l, m = Imager.image_pixels(self.psf_fov_deg, grid_size) r_lm = (l**2 + m**2)**0.5 r_lm = r_lm.flatten() idx_sorted = np.argsort(r_lm) r_lm = r_lm[idx_sorted] psf_1d = self.psf.flatten()[idx_sorted] psf_hwhm = (wavelength / (r_lm[-1] * 2.0)) / 2 # fig, ax = plt.subplots(figsize=(8, 8)) # ax.plot(r_lm, psf_1d, 'k.', ms=2, alpha=0.1) # ax.set_xscale('log') # ax.set_yscale('log') # fig.savefig('TEST_psf1d.png') # plt.close(fig) psf_1d_mean = np.zeros(num_bins) psf_1d_abs_mean = np.zeros(num_bins) psf_1d_abs_max = np.zeros(num_bins) psf_1d_min = np.zeros(num_bins) psf_1d_max = np.zeros(num_bins) psf_1d_std = np.zeros(num_bins) psf_1d_rms = np.zeros(num_bins) bin_edges = np.linspace(r_lm[0], r_lm[-1] * 2**(-0.5), num_bins + 1) # bin_edges = np.logspace(log10(r_lm[1]), log10(r_lm[-1]), # num_bins + 1) psf_1d_bin_r = (bin_edges[1:] + bin_edges[:-1]) / 2 bin_idx = np.digitize(r_lm, bin_edges) for i in range(1, num_bins + 1): values = psf_1d[bin_idx == i] if values.size > 0: psf_1d_mean[i - 1] = np.mean(values) psf_1d_abs_mean[i - 1] = np.mean(np.abs(values)) psf_1d_abs_max[i - 1] = np.max(np.abs(values)) psf_1d_min[i - 1] = np.min(values) psf_1d_max[i - 1] = np.max(values) psf_1d_std[i - 1] = np.std(values) psf_1d_rms[i - 1] = np.mean(values**2)**0.5 self.psf_1d['r'] = psf_1d_bin_r self.psf_1d['min'] = psf_1d_min self.psf_1d['max'] = psf_1d_max self.psf_1d['mean'] = psf_1d_mean self.psf_1d['std'] = psf_1d_std self.psf_1d['rms'] = psf_1d_rms self.psf_1d['abs_mean'] = psf_1d_abs_mean self.psf_1d['abs_max'] = psf_1d_abs_max fig, ax = plt.subplots(figsize=(8, 8)) ax.plot(psf_1d_bin_r, psf_1d_abs_mean, '-', c='b', lw=1, label='abs mean') ax.plot(psf_1d_bin_r, psf_1d_abs_max, '-', c='r', lw=1, label='abs max') ax.plot(psf_1d_bin_r, psf_1d_std, '-', c='g', lw=1, label='std') # ax.set_ylim(-0.1, 0.5) # ax.set_xlim(0, psf_1d_bin_r[-1] / 2**0.5) # ax.set_xscale('log') ax.set_yscale('log') ax.set_ylim(1e-4, 1) ax.set_xlim(0, psf_1d_bin_r[-1] / 2**0.5) ax.set_xlabel('PSF radius (direction cosines)') # ax.set_ylabel('PSF amplitude') ax.set_title('Azimuthally averaged PSF (FoV: %.2f)' % fov_deg) ax.legend() if filename_root: plt.savefig('%s_1d_%.1f.png' % (filename_root, fov_deg)) else: plt.show() plt.close(fig)