Beispiel #1
0
    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
Beispiel #2
0
    def __init__(self, img, gaussian, isl_idx, g_idx, flag=0):
        """Initialize Gaussian object from fitting data

        Parameters:
        img: PyBDSM image object
        gaussian: 6-tuple of fitted numbers
        isl_idx: island serial number
        g_idx: gaussian serial number
        flag: flagging (if any)
        """
        import functions as func
        from const import fwsig
        import numpy as N

        use_wcs = True
        self.gaussian_idx = g_idx
        self.gaus_num = 0 # stored later
        self.island_id = isl_idx
        self.jlevel = img.j
        self.flag = flag
        self.parameters = gaussian

        p = gaussian
        self.peak_flux = p[0]
        self.centre_pix = p[1:3]
        size = p[3:6]
        if func.approx_equal(size[0], img.pixel_beam()[0]*1.1) and \
                func.approx_equal(size[1], img.pixel_beam()[1]) and \
                func.approx_equal(size[2], img.pixel_beam()[2]+90.0) or \
                img.opts.fix_to_beam:
            # Check whether fitted Gaussian is just the distorted pixel beam
            # given as an initial guess or if size was fixed to the beam. If so,
            # reset the size to the undistorted beam.
            # Note: these are sigma sizes, not FWHM sizes.
            size = img.pixel_beam()
            size = (size[0], size[1], size[2]+90.0) # adjust angle so that corrected_size() works correctly
        size = func.corrected_size(size)  # gives fwhm and P.A.
        self.size_pix = size # FWHM in pixels and P.A. CCW from +y axis

        # Use img.orig_beam for flux calculation and deconvolution on wavelet
        # images, as img.beam has been altered to match the wavelet scale.
        # Note: these are all FWHM sizes.
        if img.waveletimage:
            bm_pix = N.array(img.beam2pix(img.orig_beam))
        else:
            bm_pix = N.array(img.beam2pix(img.beam))

        # Calculate fluxes, sky sizes, etc. All sizes are FWHM.
        tot = p[0]*size[0]*size[1]/(bm_pix[0]*bm_pix[1])
        if flag == 0:
            # These are good Gaussians
            errors = func.get_errors(img, p+[tot], img.islands[isl_idx].rms)
            self.centre_sky = img.pix2sky(p[1:3])
            self.centre_skyE = img.pix2coord(errors[1:3], self.centre_pix, use_wcs=use_wcs)
            self.size_sky = img.pix2gaus(size, self.centre_pix, use_wcs=use_wcs) # FWHM in degrees and P.A. east from north
            self.size_sky_uncorr = img.pix2gaus(size, self.centre_pix, use_wcs=False) # FWHM in degrees and P.A. east from +y axis
            self.size_skyE = img.pix2gaus(errors[3:6], self.centre_pix, use_wcs=use_wcs)
            self.size_skyE_uncorr = img.pix2gaus(errors[3:6], self.centre_pix, use_wcs=False)
            gaus_dc, err = func.deconv2(bm_pix, size)
            self.deconv_size_sky = img.pix2gaus(gaus_dc, self.centre_pix, use_wcs=use_wcs)
            self.deconv_size_sky_uncorr = img.pix2gaus(gaus_dc, self.centre_pix, use_wcs=False)
            self.deconv_size_skyE  = img.pix2gaus(errors[3:6], self.centre_pix, use_wcs=use_wcs)
            self.deconv_size_skyE_uncorr = img.pix2gaus(errors[3:6], self.centre_pix, use_wcs=False)
        else:
            # These are flagged Gaussians, so don't calculate sky values or errors
            errors = [0]*7
            self.centre_sky = [0., 0.]
            self.centre_skyE = [0., 0.]
            self.size_sky = [0., 0., 0.]
            self.size_sky_uncorr = [0., 0., 0.]
            self.size_skyE = [0., 0.]
            self.size_skyE_uncorr = [0., 0., 0.]
            self.deconv_size_sky = [0., 0., 0.]
            self.deconv_size_sky_uncorr = [0., 0., 0.]
            self.deconv_size_skyE  = [0., 0., 0.]
            self.deconv_size_skyE_uncorr = [0., 0., 0.]
        self.total_flux = tot
        self.total_fluxE = errors[6]
        self.peak_fluxE = errors[0]
        self.total_fluxE = errors[6]
        self.centre_pixE = errors[1:3]
        self.size_pixE = errors[3:6]
        self.rms = img.islands[isl_idx].rms
        self.mean = img.islands[isl_idx].mean
        self.total_flux_isl = img.islands[isl_idx].total_flux
        self.total_flux_islE = img.islands[isl_idx].total_fluxE