def fit_island_iteratively(self, img, isl, iter_ngmax=5, opts=None): """Fits an island iteratively. For large islands, which can require many Gaussians to fit well, it is much faster to fit a small number of Gaussians simultaneously and iterate. However, this does usually result in larger residuals. """ import functions as func sgaul = []; sfgaul = [] gaul = []; fgaul = [] if opts == None: opts = img.opts thresh_isl = opts.thresh_isl thresh_pix = opts.thresh_pix thresh = opts.fittedimage_clip thr = isl.mean + thresh_isl * isl.rms rms = isl.rms if opts.verbose_fitting: print 'Iteratively fitting island ', isl.island_id gaul = []; fgaul = [] ffimg_tot = N.zeros(isl.shape, dtype=N.float32) peak_val = N.max(isl.image - isl.islmean) while peak_val >= thr: sgaul, sfgaul = self.fit_island(isl, opts, img, ffimg=ffimg_tot, ngmax=iter_ngmax, ini_gausfit='simple') gaul = gaul + sgaul; fgaul = fgaul + sfgaul # Calculate residual image if len(sgaul) > 0: for g in sgaul: gcopy = g[:] gcopy[1] -= isl.origin[0] gcopy[2] -= isl.origin[1] S1, S2, Th = func.corrected_size(gcopy[3:6]) gcopy[3] = S1 gcopy[4] = S2 gcopy[5] = Th A, C1, C2, S1, S2, Th = gcopy shape = isl.shape b = find_bbox(thresh*isl.rms, gcopy) bbox = N.s_[max(0, int(C1-b)):min(shape[0], int(C1+b+1)), max(0, int(C2-b)):min(shape[1], int(C2+b+1))] x_ax, y_ax = N.mgrid[bbox] ffimg = func.gaussian_fcn(gcopy, x_ax, y_ax) ffimg_tot[bbox] += ffimg peak_val_prev = peak_val peak_val = N.max(isl.image - isl.islmean - ffimg_tot) if func.approx_equal(peak_val, peak_val_prev): break else: break if len(gaul) == 0: # Fitting iteratively did not work -- try normal fit gaul, fgaul = self.fit_island(isl, opts, img, ini_gausfit='default') return gaul, fgaul
def process_island(self, isl, img, opts=None): """Processes a single island. Returns shapelet parameters. """ if opts is None: opts = img.opts if opts.shapelet_gresid: shape = img.shape thresh = opts.fittedimage_clip model_gaus = N.zeros(shape, dtype=N.float32) for g in isl.gaul: C1, C2 = g.centre_pix b = find_bbox(thresh * isl.rms, g) bbox = N.s_[max(0, int(C1 - b)):min(shape[0], int(C1 + b + 1)), max(0, int(C2 - b)):min(shape[1], int(C2 + b + 1))] x_ax, y_ax = N.mgrid[bbox] ffimg = func.gaussian_fcn(g, x_ax, y_ax) model_gaus[bbox] = model_gaus[bbox] + ffimg arr = isl.image - isl.islmean - model_gaus[isl.bbox] if N.std(arr) < thresh * isl.rms: return [ beta, tuple(N.array(centre) + N.array(isl.origin)), nmax, basis, cf ] else: arr = isl.image - isl.islmean mask = isl.mask_active basis = opts.shapelet_basis beam_pix = img.pixel_beam() mode = opts.shapelet_fitmode if mode != 'fit': mode = '' fixed = (0, 0, 0) (beta, centre, nmax) = self.get_shapelet_params(arr, mask, basis, beam_pix, fixed, N.array(isl.origin), mode) cf = decompose_shapelets(arr, mask, basis, beta, centre, nmax, mode) return [ beta, tuple(N.array(centre) + N.array(isl.origin)), nmax, basis, cf ]
def subtract_wvgaus(self, opts, residim, gaussians, islands): import functions as func from make_residimage import Op_make_residimage as opp dummy = opp() shape = residim.shape thresh = opts.fittedimage_clip for g in gaussians: if g.valid: C1, C2 = g.centre_pix if hasattr(g, 'wisland_id'): isl = islands[g.wisland_id] else: isl = islands[g.island_id] b = opp.find_bbox(dummy, thresh * isl.rms, g) bbox = N.s_[max(0, int(C1 - b)):min(shape[0], int(C1 + b + 1)), max(0, int(C2 - b)):min(shape[1], int(C2 + b + 1))] x_ax, y_ax = N.mgrid[bbox] ffimg = func.gaussian_fcn(g, x_ax, y_ax) residim[bbox] = residim[bbox] - ffimg return residim
def process_island(self, isl, img, opts=None): """Processes a single island. Returns shapelet parameters. """ if opts == None: opts = img.opts if opts.shapelet_gresid: shape = img.shape thresh= opts.fittedimage_clip model_gaus = N.zeros(shape, dtype=N.float32) for g in isl.gaul: C1, C2 = g.centre_pix b = find_bbox(thresh*isl.rms, g) bbox = N.s_[max(0, int(C1-b)):min(shape[0], int(C1+b+1)), max(0, int(C2-b)):min(shape[1], int(C2+b+1))] x_ax, y_ax = N.mgrid[bbox] ffimg = func.gaussian_fcn(g, x_ax, y_ax) model_gaus[bbox] = model_gaus[bbox] + ffimg arr = isl.image - isl.islmean - model_gaus[isl.bbox] if N.std(arr) < thresh * isl.rms: return [beta, tuple(N.array(centre) + N.array(isl.origin)), nmax, basis, cf] else: arr = isl.image - isl.islmean mask = isl.mask_active basis = opts.shapelet_basis beam_pix = img.pixel_beam() mode = opts.shapelet_fitmode if mode != 'fit': mode = '' fixed = (0,0,0) (beta, centre, nmax) = self.get_shapelet_params(arr, mask, basis, beam_pix, fixed, N.array(isl.origin), mode) cf = decompose_shapelets(arr, mask, basis, beta, centre, nmax, mode) return [beta, tuple(N.array(centre) + N.array(isl.origin)), nmax, basis, cf]
def __call__(self, img): import functions as func from copy import deepcopy as cp import os mylog = mylogger.logging.getLogger("PyBDSM." + img.log + "ResidImage") mylog.info( "Calculating residual image after subtracting reconstructed gaussians" ) shape = img.ch0_arr.shape thresh = img.opts.fittedimage_clip resid_gaus = cp(img.ch0_arr) model_gaus = N.zeros(shape, dtype=N.float32) for g in img.gaussians: C1, C2 = g.centre_pix if hasattr(g, 'wisland_id') and img.waveletimage: isl = img.islands[g.wisland_id] else: isl = img.islands[g.island_id] b = self.find_bbox(thresh * isl.rms, g) bbox = N.s_[max(0, int(C1 - b)):min(shape[0], int(C1 + b + 1)), max(0, int(C2 - b)):min(shape[1], int(C2 + b + 1))] x_ax, y_ax = N.mgrid[bbox] ffimg = func.gaussian_fcn(g, x_ax, y_ax) resid_gaus[bbox] = resid_gaus[bbox] - ffimg model_gaus[bbox] = model_gaus[bbox] + ffimg # Apply mask to model and resid images if hasattr(img, 'rms_mask'): mask = img.rms_mask else: mask = img.mask_arr if isinstance(img.mask_arr, N.ndarray): pix_masked = N.where(img.mask_arr == True) model_gaus[pix_masked] = N.nan resid_gaus[pix_masked] = N.nan img.model_gaus_arr = model_gaus img.resid_gaus_arr = resid_gaus if img.opts.output_all: if img.waveletimage: resdir = img.basedir + '/wavelet/residual/' moddir = img.basedir + '/wavelet/model/' else: resdir = img.basedir + '/residual/' moddir = img.basedir + '/model/' if not os.path.exists(resdir): os.makedirs(resdir) if not os.path.exists(moddir): os.makedirs(moddir) func.write_image_to_file(img.use_io, img.imagename + '.resid_gaus.fits', resid_gaus, img, resdir) mylog.info( '%s %s' % ('Writing', resdir + img.imagename + '.resid_gaus.fits')) func.write_image_to_file(img.use_io, img.imagename + '.model.fits', (img.ch0_arr - resid_gaus), img, moddir) mylog.info( '%s %s' % ('Writing', moddir + img.imagename + '.model_gaus.fits')) ### residual rms and mean per island for isl in img.islands: resid = resid_gaus[isl.bbox] self.calc_resid_mean_rms(isl, resid, type='gaus') # Calculate some statistics for the Gaussian residual image non_masked = N.where(~N.isnan(img.ch0_arr)) mean = N.mean(resid_gaus[non_masked], axis=None) std_dev = N.std(resid_gaus[non_masked], axis=None) skew = stats.skew(resid_gaus[non_masked], axis=None) kurt = stats.kurtosis(resid_gaus[non_masked], axis=None) stat_msg = "Statistics of the Gaussian residual image:\n" stat_msg += " mean: %.3e (Jy/beam)\n" % mean stat_msg += " std. dev: %.3e (Jy/beam)\n" % std_dev stat_msg += " skew: %.3f\n" % skew stat_msg += " kurtosis: %.3f" % kurt mylog.info(stat_msg) # Now residual image for shapelets if img.opts.shapelet_do: mylog.info( "Calculating residual image after subtracting reconstructed shapelets" ) shape = img.ch0_arr.shape fimg = N.zeros(shape, dtype=N.float32) for isl in img.islands: if isl.shapelet_beta > 0: # make sure shapelet has nonzero scale for this island mask = isl.mask_active cen = isl.shapelet_centre - N.array(isl.origin) basis, beta, nmax, cf = isl.shapelet_basis, isl.shapelet_beta, \ isl.shapelet_nmax, isl.shapelet_cf image_recons = reconstruct_shapelets( isl.shape, mask, basis, beta, cen, nmax, cf) fimg[isl.bbox] += image_recons model_shap = fimg resid_shap = img.ch0_arr - fimg # Apply mask to model and resid images if hasattr(img, 'rms_mask'): mask = img.rms_mask else: mask = img.mask_arr if isinstance(mask, N.ndarray): pix_masked = N.where(mask == True) model_shap[pix_masked] = N.nan resid_shap[pix_masked] = N.nan img.model_shap_arr = model_shap img.resid_shap_arr = resid_shap if img.opts.output_all: func.write_image_to_file(img.use_io, img.imagename + '.resid_shap.fits', resid_shap, img, resdir) mylog.info( '%s %s' % ('Writing ', resdir + img.imagename + '.resid_shap.fits')) ### shapelet residual rms and mean per island for isl in img.islands: resid = resid_shap[isl.bbox] self.calc_resid_mean_rms(isl, resid, type='shap') # Calculate some statistics for the Shapelet residual image non_masked = N.where(~N.isnan(img.ch0_arr)) mean = N.mean(resid_shap[non_masked], axis=None) std_dev = N.std(resid_shap[non_masked], axis=None) skew = stats.skew(resid_shap[non_masked], axis=None) kurt = stats.kurtosis(resid_shap[non_masked], axis=None) mylog.info("Statistics of the Shapelet residual image:") mylog.info(" mean: %.3e (Jy/beam)" % mean) mylog.info(" std. dev: %.3e (Jy/beam)" % std_dev) mylog.info(" skew: %.3f" % skew) mylog.info(" kurtosis: %.3f" % kurt) img.completed_Ops.append('make_residimage') return img
def __call__(self, img): import functions as func from copy import deepcopy as cp import os mylog = mylogger.logging.getLogger("PyBDSM."+img.log+"ResidImage") mylog.info("Calculating residual image after subtracting reconstructed gaussians") shape = img.ch0_arr.shape thresh= img.opts.fittedimage_clip resid_gaus = cp(img.ch0_arr) model_gaus = N.zeros(shape, dtype=N.float32) for g in img.gaussians: C1, C2 = g.centre_pix if hasattr(g, 'wisland_id') and img.waveletimage: isl = img.islands[g.wisland_id] else: isl = img.islands[g.island_id] b = self.find_bbox(thresh*isl.rms, g) bbox = N.s_[max(0, int(C1-b)):min(shape[0], int(C1+b+1)), max(0, int(C2-b)):min(shape[1], int(C2+b+1))] x_ax, y_ax = N.mgrid[bbox] ffimg = func.gaussian_fcn(g, x_ax, y_ax) resid_gaus[bbox] = resid_gaus[bbox] - ffimg model_gaus[bbox] = model_gaus[bbox] + ffimg # Apply mask to model and resid images if hasattr(img, 'rms_mask'): mask = img.rms_mask else: mask = img.mask_arr if isinstance(img.mask_arr, N.ndarray): pix_masked = N.where(img.mask_arr == True) model_gaus[pix_masked] = N.nan resid_gaus[pix_masked] = N.nan img.model_gaus_arr = model_gaus img.resid_gaus_arr = resid_gaus if img.opts.output_all: if img.waveletimage: resdir = img.basedir + '/wavelet/residual/' moddir = img.basedir + '/wavelet/model/' else: resdir = img.basedir + '/residual/' moddir = img.basedir + '/model/' if not os.path.exists(resdir): os.makedirs(resdir) if not os.path.exists(moddir): os.makedirs(moddir) func.write_image_to_file(img.use_io, img.imagename + '.resid_gaus.fits', resid_gaus, img, resdir) mylog.info('%s %s' % ('Writing', resdir+img.imagename+'.resid_gaus.fits')) func.write_image_to_file(img.use_io, img.imagename + '.model.fits', (img.ch0_arr - resid_gaus), img, moddir) mylog.info('%s %s' % ('Writing', moddir+img.imagename+'.model_gaus.fits')) ### residual rms and mean per island for isl in img.islands: resid = resid_gaus[isl.bbox] self.calc_resid_mean_rms(isl, resid, type='gaus') # Calculate some statistics for the Gaussian residual image non_masked = N.where(~N.isnan(img.ch0_arr)) mean = N.mean(resid_gaus[non_masked], axis=None) std_dev = N.std(resid_gaus[non_masked], axis=None) skew = stats.skew(resid_gaus[non_masked], axis=None) kurt = stats.kurtosis(resid_gaus[non_masked], axis=None) stat_msg = "Statistics of the Gaussian residual image:\n" stat_msg += " mean: %.3e (Jy/beam)\n" % mean stat_msg += " std. dev: %.3e (Jy/beam)\n" % std_dev stat_msg += " skew: %.3f\n" % skew stat_msg += " kurtosis: %.3f" % kurt mylog.info(stat_msg) # Now residual image for shapelets if img.opts.shapelet_do: mylog.info("Calculating residual image after subtracting reconstructed shapelets") shape = img.ch0_arr.shape fimg = N.zeros(shape, dtype=N.float32) for isl in img.islands: if isl.shapelet_beta > 0: # make sure shapelet has nonzero scale for this island mask=isl.mask_active cen=isl.shapelet_centre-N.array(isl.origin) basis, beta, nmax, cf = isl.shapelet_basis, isl.shapelet_beta, \ isl.shapelet_nmax, isl.shapelet_cf image_recons=reconstruct_shapelets(isl.shape, mask, basis, beta, cen, nmax, cf) fimg[isl.bbox] += image_recons model_shap = fimg resid_shap = img.ch0_arr - fimg # Apply mask to model and resid images if hasattr(img, 'rms_mask'): mask = img.rms_mask else: mask = img.mask_arr if isinstance(mask, N.ndarray): pix_masked = N.where(mask == True) model_shap[pix_masked] = N.nan resid_shap[pix_masked] = N.nan img.model_shap_arr = model_shap img.resid_shap_arr = resid_shap if img.opts.output_all: func.write_image_to_file(img.use_io, img.imagename + '.resid_shap.fits', resid_shap, img, resdir) mylog.info('%s %s' % ('Writing ', resdir+img.imagename+'.resid_shap.fits')) ### shapelet residual rms and mean per island for isl in img.islands: resid = resid_shap[isl.bbox] self.calc_resid_mean_rms(isl, resid, type='shap') # Calculate some statistics for the Shapelet residual image non_masked = N.where(~N.isnan(img.ch0_arr)) mean = N.mean(resid_shap[non_masked], axis=None) std_dev = N.std(resid_shap[non_masked], axis=None) skew = stats.skew(resid_shap[non_masked], axis=None) kurt = stats.kurtosis(resid_shap[non_masked], axis=None) mylog.info("Statistics of the Shapelet residual image:") mylog.info(" mean: %.3e (Jy/beam)" % mean) mylog.info(" std. dev: %.3e (Jy/beam)" % std_dev) mylog.info(" skew: %.3f" % skew) mylog.info(" kurtosis: %.3f" % kurt) img.completed_Ops.append('make_residimage') return img