Ejemplo n.º 1
0
def moffat_ee(fwhm=1.0, alpha=3.0, max_aperture=3.0):
    """ Compute the encircled energy for a Moffat profile, given the FWHM """

    # Find the value of Moffat gamma that gives the required FWHM
    gamma_arr = np.arange(fwhm * 0.5, fwhm * 2, fwhm * 1e-2)
    m_arr = Moffat2D(1.0, 0.0, 0.0, gamma_arr, alpha)
    gamma = np.interp(fwhm, m_arr.fwhm, gamma_arr)

    # Create a Moffat profile with the required FWHM
    m = Moffat2D(1.0, 0.0, 0.0, gamma, alpha)
    grid = np.arange(0, max_aperture, 1e-2)
    grid_ext = np.arange(0, max_aperture * 10, 1e-2)
    x, y = np.meshgrid(grid, grid)
    x_ext, y_ext = np.meshgrid(grid_ext, grid_ext)
    m.x = x
    m.y = y
    m.z = m(x, y)
    zsum = np.sum(m(x_ext, y_ext))

    # Compute the encircled energy
    m.ee = []
    m.rad = np.arange(0, max_aperture, 1e-2)
    for r in m.rad:
        where = x**2 + y**2 < r**2
        m.zin = np.zeros((len(x), len(y)))
        m.zin[where] = m.z[where]

        # Compute the encircled energy
        m.ee.append(np.sum(m.zin) / zsum)
    return m
Ejemplo n.º 2
0
   def create_modelled_profiles(self, img, metadata):
        """Create the cutouts from positions given in pixels."""

        nprofs = len(metadata)
        profiles = np.zeros(shape=(npos, 60, 60), dtype = np.float32)
        xgrid,ygrid = np.meshgrid(np.arange(0,600,1), np.arange(0,600,1))
        xgrid_psf,ygrid_psf = np.meshgrid(np.arange(0,400,1), np.arange(0,400,1))
        
        for i in range(nprofs):
            #cosmos_pixelscale = 0.03, paus_pixelscale = 0.263, draw profile in a x10 resolution grid
            r50, n, ellip, psf, Iauto, x, y, theta = 10*metadata.r50 * 0.03 / 0.263, metadata.sersic_n_gim2d, 1 - metadata.aperture_b/metadata.aperture_a,\
            10* metadata.psf_fwhm /0.263, metadata.I_auto, metadata.aperture_y, metadata.aperture_x,  (180 - metadata.aperture_theta)*(2*np.pi/360)
            
            #create the galaxy profile: 
            mod = Sersic2D(amplitude = 1, r_eff =r50, n=n, x_0=300+dx, y_0=300+dy,theta =  theta, ellip = ellip)
            prof =  mod(xgrid, ygrid)
            
            #create the PSF profile: 
            gam = psf / (2. * np.sqrt(np.power(2., 1 / alph ) - 1.))
            amp = (alph - 1) / (np.pi * gam**2)
            moff = Moffat2D(amplitude=amp, x_0 = 200, y_0 = 200, gamma=gam, alpha=alph)
            prof_psf = moff(xgrid_psf, ygrid_psf)
            
            #convolve the profile, reduce to pixel resolution and normalise it
            prof_conv = fftconvolve(prof,prof_psf, mode = 'same')
            prof_conv = block_reduce(prof_conv, (10,10), np.mean)
            prof_conv = prof_conv / prof_conv.max()

            profiles[i] = prof_conv
     
        return profiles
Ejemplo n.º 3
0
 def moffat(self, cen=psf_cen):
     ampl = 1
     alpha = 3
     gamma = self.seeing.value / 2 / np.sqrt(2**(1 / alpha) - 1)
     m = Moffat2D(1, cen[0], cen[1], gamma, alpha)
     self.z = m.evaluate(self.x, self.y, ampl, cen[0], cen[1], gamma, alpha)
     self.fwhm = m.fwhm
Ejemplo n.º 4
0
 def _setPSFModel(self, model):
     if model == 'gaussian':
         self._setGaussianModel()
         self._gaussianModel = Gaussian2D(amplitude=self._amplitude,
                                          x_stddev=self._sx,
                                          y_stddev=self._sy,
                                          x_mean=self._xMean,
                                          y_mean=self._yMean,
                                          theta=self._theta)
         self._gaussianModel.fluxname = 'amplitude'
         self._gaussianModel.xname = 'x_mean'
         self._gaussianModel.yname = 'y_mean'
         self._psfModel = self._gaussianModel
     elif model == 'moffat':
         self._setMoffatModel()
         self._moffatModel = Moffat2D(amplitude=self._amplitude,
                                      x_0=self._x0,
                                      y_0=self._y0,
                                      gamma=self._gamma,
                                      alpha=self._alpha)
         self._moffatModel.fluxname = 'amplitude'
         self._psfModel = self._moffatModel
     elif model == 'integrated gaussian':
         self._setIntGaussianModel()
         self._psfModel = IntegratedGaussianPRF(sigma=self._sigma,
                                                flux=self._flux,
                                                x_0=self._xPeak,
                                                y_0=self._yPeak)
     else:
         self._psfModel = model
Ejemplo n.º 5
0
def fit_moff(image,
             x0,
             y0,
             gate,
             debug,
             fig_name=None,
             centring=False,
             silent=False):
    data_fit = image[y0 - gate:y0 + gate, x0 - gate:x0 + gate]
    if centring:
        if not silent:
            print("centring...")
        # ------------------------------------------------------------------ find brighter pixel and center it!!!!
        bx0, by0 = np.unravel_index(data_fit.argmax(), data_fit.shape)
        if not silent:
            print("bx, by=", bx0, by0)

        sx = by0 - gate
        sy = bx0 - gate

        data_fit = image[y0 - gate + sy:y0 + gate + sy,
                         x0 - gate + sx:x0 + gate + sx]
        # ----------------------------------------------------------------------------------------
    Z3 = data_fit
    X3 = np.arange(0, gate * 2, 1)
    Y3 = np.arange(0, gate * 2, 1)
    X3, Y3 = np.meshgrid(X3, Y3)

    m_init = Moffat2D(amplitude=np.max(Z3),
                      x_0=gate,
                      y_0=gate,
                      gamma=1.,
                      alpha=1.0)
    fit_m = fitting.LevMarLSQFitter()
    with warnings.catch_warnings():
        # Ignore model linearity warning from the fitter
        warnings.simplefilter('ignore')
        m = fit_m(m_init, X3, Y3, Z3)
    # print("#####Moffat#########")
    # print(m.x_0.value)
    # print(m.y_0.value)

    Zmm = m(X3, Y3)
    RMSE, Rsquared = R2_calc(Zmm, Z3)
    # print("x=%2.3f  y=%2.3f   R^2=%2.4f" % (m.x_0.value + xs - gate, m.y_0.value + ys - gate, Rsquared))
    amp = np.max(Z3)
    target = [
        x0 - gate + m.x_0.value, y0 - gate + m.y_0.value, m.fwhm, Rsquared, amp
    ]
    if debug:
        # plotting(data_fit, par, save=True, filename=fig_name, par=target, gate=gate)
        par = [m.x_0.value, m.y_0.value, m.fwhm]
        plotting(data_fit,
                 par,
                 save=True,
                 filename=fig_name,
                 par=par,
                 err=[0., 0.],
                 tar=target,
                 gate=gate)
    return target
Ejemplo n.º 6
0
def make_seeing_psf(filt_name):
    psf_file = 'seeing_psf_{0:s}.pickle'.format(filt_name)

    # Note that seeing is taken as FWHM.
    seeing = 0.86 # arcsec specified at 5000 Angstrom
    
    wave = filt_wave[filt_name] # In Angstroms
    print 'Seeing at 5000 Angstroms:', seeing

    seeing *= (wave / 5000)**(-1./5.)
    print 'Seeing at {0:s} band:'.format(filt_name), seeing
    
    # Make a very over-sampled PSF and do integrals
    # on that... faster than scipy.integrate.
    print 'Prep'
    pix_scale = 0.01 # arcsec
    
    xy1d = np.arange(-10*seeing, 10*seeing, pix_scale)
    
    x, y = np.meshgrid(xy1d, xy1d)
    
    # Use a 2D Gaussian as our PSF.
    # print 'Make Gaussian sigma=', seeing/2.35
    # psf = Gaussian2D.evaluate(x, y, 1, 0, 0, seeing/2.35, seeing/2.35, 0)

    # Use a 2D Moffatt as our PSF.
    alpha = 2.5
    gamma = seeing / (2.0 * (2**(1.0/alpha) - 1)**0.5)
    print 'Make Moffat 2D alpha=2.5, gamma=', gamma
    psf = Moffat2D.evaluate(x, y, 1, 0, 0, gamma, alpha)
    
    # Integrate over each pixel
    print 'Integrate and normalize'
    psf *= pix_scale**2
    
    # Normalize
    psf /= psf.sum()
    
    # Get the radius of each pixel
    r = np.hypot(x, y)

    # Make an encircled energy curve.
    r_save = np.arange(0.025, 2, 0.025)
    ee_save = np.zeros(len(r_save), dtype=float)

    for rr in range(len(r_save)):
        print 'Integrating for ', r_save[rr]
        idx = np.where(r < r_save[rr])

        ee_save[rr] = psf[idx].sum()

    # Make an ensquared energy curve.
    sq_diam_save = np.arange(0.025, 2, 0.025)
    sq_ee_save = np.zeros(len(sq_diam_save), dtype=float)

    x_dist = np.abs(x)
    y_dist = np.abs(y)
    
    for ii in range(len(sq_diam_save)):
        print 'Integrating over square diameter: ', sq_diam_save[ii]
        dist = sq_diam_save[ii] / 2.0
        idx = np.where((x_dist < dist) & (y_dist < dist))

        sq_ee_save[ii] = psf[idx].sum()
        
        
    print 'Save'
    _psf = open(psf_file, 'w')
    pickle.dump(r_save, _psf)
    pickle.dump(ee_save, _psf)
    pickle.dump(sq_diam_save, _psf)
    pickle.dump(sq_ee_save, _psf)
    _psf.close()

    return
Ejemplo n.º 7
0
# fitshape
# fitshape=(5,5) # must be odd values
# fitshape=(7,7) # must be odd values
# fitshape=(9,9) # must be odd values
# 2xfwhm ?

# array shape
xyshape = np.shape(imdata)
n_px = xyshape[0]
#y, x = np.mgrid[:xyshape[0], :xyshape[1]]
x, y = np.mgrid[:n_px, :n_px]

x0 = 1028.
y0 = 1021.
model_data = Moffat2D(1, 1028, 1021)

# psf_model
from photutils.psf import IntegratedGaussianPRF
psf_model = IntegratedGaussianPRF(sigma=sigma_psf)

#
from astropy.modeling import Fittable2DModel
model2d = Fittable2DModel(model_data)
#model2d = FittableImageModel(model_data)
result = fitter(model_data, x, y, imdata)
#result = fitter(model2d, x, y, imdata)
print(result)
print(np.median(imdata), np.max(imdata), np.sum(imdata))

# finder