示例#1
0
def _meisner_psf_models():
    global plotslice
    # Meisner's PSF models
    # for band in [4]:
    for band in [1, 2, 3, 4]:
        print()
        print('W%i' % band)
        print()

        #pix = fitsio.read('wise-psf-avg-pix.fits', ext=band-1)
        pix = fitsio.read('wise-psf-avg-pix-bright.fits', ext=band - 1)
        fit = fits_table('wise-psf-avg.fits', hdu=band)
        #fit = fits_table('psf-allwise-con3.fits', hdu=band)

        scale = 1.

        print('Pix shape', pix.shape)
        h, w = pix.shape

        xx, yy = np.meshgrid(np.arange(w), np.arange(h))
        cx, cy = np.sum(xx * pix) / np.sum(pix), np.sum(yy * pix) / np.sum(pix)
        print('Centroid:', cx, cy)

        #S = 100
        S = h / 2
        slc = slice(h / 2 - S, h / 2 + S + 1), slice(w / 2 - S, w / 2 + S + 1)

        plotss = 30
        plotslice = slice(S - plotss,
                          -(S - plotss)), slice(S - plotss, -(S - plotss))

        opix = pix
        print('Original pixels sum:', opix.sum())
        pix /= pix.sum()
        pix = pix[slc]
        print('Sliced pix sum', pix.sum())

        psf = GaussianMixturePSF(fit.amp, fit.mean * scale, fit.var * scale**2)
        psfmodel = psf.getPointSourcePatch(0., 0., radius=h / 2)
        mod = psfmodel.patch
        print('Orig mod sum', mod.sum())
        mod = mod[slc]
        print('Sliced mod sum', mod.sum())
        print('Amps:', np.sum(psf.mog.amp))

        _plot_psf(pix, mod, psf)
        plt.suptitle('W%i: Orig' % band)
        ps.savefig()

        # Lanczos sub-sample
        if band == 4:
            lpix = _lanczos_subsample(opix, 2)
            pix = lpix
            h, w = pix.shape

            #S = 140
            slc = slice(h / 2 - S,
                        h / 2 + S + 1), slice(w / 2 - S, w / 2 + S + 1)
            print('Resampled pix sum', pix.sum())
            pix = pix[slc]
            print('sliced pix sum', pix.sum())

            psf = GaussianMixturePSF(fit.amp, fit.mean * scale,
                                     fit.var * scale**2)
            psfmodel = psf.getPointSourcePatch(0., 0., radius=h / 2)
            mod = psfmodel.patch
            print('Scaled mod sum', mod.sum())
            mod = mod[slc]
            print('Sliced mod sum', mod.sum())

            _plot_psf(pix, mod, psf)
            plt.suptitle('W%i: Scaled' % band)
            ps.savefig()

            plotslice = slice(S - plotss,
                              -(S - plotss)), slice(S - plotss, -(S - plotss))

        psfx = GaussianMixturePSF.fromStamp(pix,
                                            P0=(fit.amp, fit.mean * scale,
                                                fit.var * scale**2))
        psfmodel = psfx.getPointSourcePatch(0., 0., radius=h / 2)
        mod = psfmodel.patch
        print('From stamp: mod sum', mod.sum())
        mod = mod[slc]
        print('Sliced mod sum:', mod.sum())
        _plot_psf(pix, mod, psfx)
        plt.suptitle('W%i: fromStamp: %g = %s, res %.3f' %
                     (band, np.sum(psfx.mog.amp), ','.join(
                         ['%.3f' % a
                          for a in psfx.mog.amp]), np.sum(pix - mod)))
        ps.savefig()

        print('Stamp-Fit PSF params:', psfx)

        # class MyGaussianMixturePSF(GaussianMixturePSF):
        #     def getLogPrior(self):
        #         if np.any(self.mog.amp < 0.):
        #             return -np.inf
        #         for k in range(self.mog.K):
        #             if np.linalg.det(self.mog.var[k]) <= 0:
        #                 return -np.inf
        #         return 0
        #
        #     @property
        #     def amp(self):
        #         return self.mog.amp
        #
        # mypsf = MyGaussianMixturePSF(psfx.mog.amp, psfx.mog.mean, psfx.mog.var)
        # mypsf.radius = sh/2

        sh, sw = pix.shape

        # Initialize from original fit params
        psfx = psf

        # Try concentric gaussian PSF
        sigmas = []
        for k in range(psfx.mog.K):
            v = psfx.mog.var[k, :, :]
            sigmas.append(np.sqrt(np.sqrt(np.abs(v[0, 0] * v[1, 1]))))
        print('Initializing concentric Gaussian PSF with sigmas', sigmas)
        gpsf = NCircularGaussianPSF(sigmas, psfx.mog.amp)
        gpsf.radius = sh / 2
        mypsf = gpsf

        tim = Image(data=pix, invvar=1e6 * np.ones_like(pix), psf=mypsf)
        tim.modelMinval = 1e-16

        # xx,yy = np.meshgrid(np.arange(sw), np.arange(sh))
        # cx,cy = np.sum(xx*pix)/np.sum(pix), np.sum(yy*pix)/np.sum(pix)
        # print 'Centroid:', cx,cy
        # print 'Pix midpoint:', sw/2, sh/2
        cx, cy = sw / 2, sh / 2
        src = PointSource(PixPos(cx, cy), Flux(1.0))

        tractor = Tractor([tim], [src])

        tim.freezeAllBut('psf')
        # tractor.freezeParam('catalog')
        src.freezeAllBut('pos')

        # src.freezeAllBut('brightness')
        # tractor.freezeParam('images')
        # tractor.optimize_forced_photometry()
        # tractor.thawParam('images')
        # print 'Source flux after forced-photom fit:', src.getBrightness()

        print('Optimizing Params:')
        tractor.printThawedParams()

        for i in range(200):
            #dlnp,X,alpha = tractor.optimize(damp=0.1)
            dlnp, X, alpha = tractor.optimize(damp=1)
            print(i, 'dlnp %.3g' % dlnp, 'psf', gpsf)
            if dlnp < 1e-6:
                break

        tractor.freezeParam('catalog')
        gpsf.sigmas.stepsize = len(gpsf.sigmas) * [1e-6]
        gpsf.weights.stepsize = len(gpsf.sigmas) * [1e-6]

        for i in range(200):
            #dlnp,X,alpha = tractor.optimize(damp=0.1)
            dlnp, X, alpha = tractor.optimize(damp=1)
            print(i, 'dlnp %.3g' % dlnp, 'psf', gpsf)
            if dlnp < 1e-6:
                break

        print('PSF3(opt): flux', src.brightness)
        print('PSF amps:', np.sum(mypsf.amp))
        print('PSF amps * Source brightness:',
              src.brightness.getValue() * np.sum(mypsf.amp))
        print('pix sum:', pix.sum())

        print('Optimize source:', src)
        print('Optimized PSF:', mypsf)

        mod = tractor.getModelImage(0)
        print('Mod sum:', mod.sum())
        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(
                         ['%.3f' % a for a in mypsf.amp]), np.sum(pix - mod)))
        ps.savefig()

        # Write before normalizing!
        T = fits_table()
        T.amp = mypsf.mog.amp
        T.mean = mypsf.mog.mean
        T.var = mypsf.mog.var
        T.writeto('psf3-w%i.fits' % band)
        T.writeto('psf3.fits', append=(band != 1))

        mypsf.weights.setParams(
            np.array(mypsf.weights.getParams()) /
            sum(mypsf.weights.getParams()))
        print('Normalized PSF weights:', mypsf)
        mod = tractor.getModelImage(0)
        print('Mod sum:', mod.sum())
        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(
                         ['%.3f' % a for a in mypsf.amp]), np.sum(pix - mod)))
        ps.savefig()

        class MyGaussianPSF(NCircularGaussianPSF):
            '''
            A PSF model with strictly positive weights that sum to
            unity.
            '''
            def __init__(self, sigmas, weights):
                ww = np.array(weights)
                ww = np.log(ww)
                super(MyGaussianPSF, self).__init__(sigmas, ww)

            @staticmethod
            def getNamedParams():
                return dict(sigmas=0, logweights=1)

            def __str__(self):
                return ('MyGaussianPSF: sigmas [ ' +
                        ', '.join(['%.3f' % s for s in self.mysigmas]) +
                        ' ], weights [ ' +
                        ', '.join(['%.3f' % w for w in self.myweights]) + ' ]')

            @property
            def myweights(self):
                ww = np.exp(self.logweights.getAllParams())
                ww /= ww.sum()
                return ww

            @property
            def weights(self):
                ww = np.exp(self.logweights.getParams())
                wsum = np.sum(np.exp(self.logweights.getAllParams()))
                return ww / wsum

        if band == 4:
            # HACK
            mypsf = MyGaussianPSF([1.7, 6.4, 15.0], [0.333, 0.666, 0.1])
        else:
            mypsf = MyGaussianPSF(gpsf.sigmas, gpsf.amp)
        mypsf.radius = sh / 2

        tim.psf = mypsf

        print('Optimizing Params:')
        tractor.printThawedParams()

        for i in range(200):
            #dlnp,X,alpha = tractor.optimize(damp=0.1)
            dlnp, X, alpha = tractor.optimize(damp=1)
            print(i, 'dlnp %.3g' % dlnp, 'psf', mypsf)
            if dlnp < 1e-6:
                break

        mypsf.sigmas.stepsize = len(mypsf.sigmas) * [1e-6]
        mypsf.logweights.stepsize = len(mypsf.sigmas) * [1e-6]

        for i in range(200):
            #dlnp,X,alpha = tractor.optimize(damp=0.1)
            dlnp, X, alpha = tractor.optimize(damp=1)
            print(i, 'dlnp %.3g' % dlnp, 'psf', mypsf)
            if dlnp < 1e-6:
                break

        print('PSF amps:', np.sum(mypsf.amp))
        print('pix sum:', pix.sum())
        print('Optimize source:', src)
        print('Optimized PSF:', mypsf)

        mod = tractor.getModelImage(0)
        print('Mod sum:', mod.sum())
        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt2): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(
                         ['%.3f' % a for a in mypsf.amp]), np.sum(pix - mod)))
        ps.savefig()

        # Write
        mog = mypsf.getMixtureOfGaussians()
        T = fits_table()
        T.amp = mog.amp
        T.mean = mog.mean
        T.var = mog.var
        T.writeto('psf4.fits', append=(band != 1))
示例#2
0
def _allwise_psf_models():
    global plotslice
    # AllWISE PSF models
    for band in [1, 2, 3, 4]:
        print()
        print('W%i' % band)
        print()

        pix = reduce(np.add, [
            fitsio.read('wise-w%i-psf-wpro-09x09-%02ix%02i.fits' %
                        (band, 1 + (i / 9), 1 + (i % 9))) for i in range(9 * 9)
        ])
        print('Pix', pix.shape)
        h, w = pix.shape
        print('Pix sum', pix.sum())
        print('Pix max', pix.max())
        pix /= pix.sum()

        psf = GaussianMixturePSF.fromStamp(pix)
        print('Fit PSF', psf)
        psfmodel = psf.getPointSourcePatch(0., 0., radius=h / 2)
        mod = psfmodel.patch
        print('Orig mod sum', mod.sum())

        S = h / 2
        plotss = 30
        plotslice = slice(S - plotss,
                          -(S - plotss)), slice(S - plotss, -(S - plotss))

        _plot_psf(pix, mod, psf)
        plt.suptitle('W%i: from stamp' % band)
        ps.savefig()

        # Try concentric gaussian PSF
        sh, sw = pix.shape
        sigmas = []
        for k in range(psf.mog.K):
            v = psf.mog.var[k, :, :]
            sigmas.append(np.sqrt(np.sqrt(v[0, 0] * v[1, 1])))

        print('Initializing concentric Gaussian model with sigmas', sigmas)
        print('And weights', psf.mog.amp)

        # (Initial) W1:
        # sig [7.1729391870564569, 24.098952864976805, 108.78869923786333]
        # weights [ 0.80355109  0.15602835  0.04195982]
        # sigmas [ 6.928, 17.091, 45.745 ], weights [ 0.760, 0.154, 0.073 ]

        # W2:
        # sig [8.2356371659198189, 25.741694812001221, 110.17431488810806]
        # weights [ 0.80636191  0.1563742   0.03926182]
        # sigmas [ 7.177, 10.636, 30.247 ], weights [ 0.500, 0.341, 0.134 ]

        # W3:
        # sig [6.860124763919889, 19.160849966251824, 134.20812055907825]
        # weights [ 0.28227047  0.55080156  0.16706357]
        # sigmas [ 6.850, 18.922, 109.121 ], weights [ 0.276, 0.554, 0.148 ]

        # W4:
        # [4.6423676603462001, 5.31542132669962, 18.375512539373585]
        # weights [ 0.10764341  0.26915295  0.62320374]
        # (Opt)
        # sigmas [ 6.293, 6.314, 20.932 ], weights [ 0.129, 0.309, 0.598 ]

        weights = psf.mog.amp

        # HACK
        if band == 4:
            sigmas = [2., 6., 25.]
            weights = [0.5, 0.25, 0.25]
        else:
            sigmas = [8., 24., 100.]
            weights = [0.5, 0.25, 0.25]

        gpsf = NCircularGaussianPSF(sigmas, weights)
        gpsf.radius = sh / 2
        mypsf = gpsf
        tim = Image(data=pix, invvar=1e6 * np.ones_like(pix), psf=mypsf)
        cx, cy = sw / 2, sh / 2
        src = PointSource(PixPos(cx, cy), Flux(1.0))

        tractor = Tractor([tim], [src])

        tim.freezeAllBut('psf')
        # tractor.freezeParam('catalog')
        src.freezeAllBut('pos')

        print('Optimizing Params:')
        tractor.printThawedParams()

        for i in range(100):
            dlnp, X, alpha = tractor.optimize(damp=0.1)
            print('dlnp', dlnp)
            print('PSF', mypsf)
            if dlnp < 0.001:
                break

        print('PSF3(opt): flux', src.brightness)
        print('PSF amps:', np.sum(mypsf.amp))
        print('PSF amps * Source brightness:',
              src.brightness.getValue() * np.sum(mypsf.amp))
        print('pix sum:', pix.sum())

        print('Optimize source:', src)
        print('Optimized PSF:', mypsf)

        mod = tractor.getModelImage(0)
        print('Mod sum:', mod.sum())
        print('Mod min:', mod.min())
        print('Mod max:', mod.max())

        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(
                         ['%.3f' % a for a in mypsf.amp]), np.sum(pix - mod)))
        ps.savefig()

        # These postage stamps are subsampled at 8x the 2.75"/pix,
        # except for the W4 one, which is at 4x that.
        scale = 8
        if band == 4:
            scale = 4

        T = fits_table()
        T.amp = mypsf.mog.amp
        T.mean = mypsf.mog.mean / scale
        T.var = mypsf.mog.var / scale**2
        T.writeto('psf-allwise-con3-w%i.fits' % band)
        T.writeto('psf-allwise-con3.fits', append=(band != 1))

        mypsf.weights.setParams(
            np.array(mypsf.weights.getParams()) /
            sum(mypsf.weights.getParams()))
        print('Normalized PSF weights:', mypsf)
        mod = tractor.getModelImage(0)
        print('Mod sum:', mod.sum())
        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(
                         ['%.3f' % a for a in mypsf.amp]), np.sum(pix - mod)))
        ps.savefig()
示例#3
0
    psf2 = GaussianMixturePSF(mypsf.mog.amp[:2] / mypsf.mog.amp[:2].sum(),
                              mypsf.mog.mean[:2, :], mypsf.mog.var[:2, :, :])
    psf2.radius = sh / 2
    tim.psf = psf2
    mod = tractor.getModelImage(0)
    _plot_psf(lpix, mod, psf2, flux=src.brightness.getValue())
    plt.suptitle('psf2 (init)')
    ps.savefig()

    src.freezeAllBut('brightness')
    tractor.freezeParam('catalog')
    for i in range(100):

        print('Optimizing PSF:')
        tractor.printThawedParams()

        dlnp, X, alpha = tractor.optimize(damp=1.)

        tractor.freezeParam('images')
        tractor.thawParam('catalog')

        print('Optimizing flux:')
        tractor.printThawedParams()

        tractor.optimize_forced_photometry()
        tractor.thawParam('images')
        tractor.freezeParam('catalog')

    mod = tractor.getModelImage(0)
    _plot_psf(lpix, mod, psf2, flux=src.brightness.getValue())
示例#4
0
def _meisner_psf_models():
    global plotslice
    # Meisner's PSF models
    #for band in [4]:
    for band in [1,2,3,4]:
        print
        print 'W%i' % band
        print
        
        #pix = fitsio.read('wise-psf-avg-pix.fits', ext=band-1)
        pix = fitsio.read('wise-psf-avg-pix-bright.fits', ext=band-1)
        fit = fits_table('wise-psf-avg.fits', hdu=band)
        #fit = fits_table('psf-allwise-con3.fits', hdu=band)
    
        scale = 1.
    
        print 'Pix shape', pix.shape
        h,w = pix.shape

        xx,yy = np.meshgrid(np.arange(w), np.arange(h))
        cx,cy = np.sum(xx*pix)/np.sum(pix), np.sum(yy*pix)/np.sum(pix)
        print 'Centroid:', cx,cy

        #S = 100
        S = h/2
        slc = slice(h/2-S, h/2+S+1), slice(w/2-S, w/2+S+1)

        plotss = 30
        plotslice = slice(S-plotss, -(S-plotss)), slice(S-plotss, -(S-plotss))
        
        opix = pix
        print 'Original pixels sum:', opix.sum()
        pix /= pix.sum()
        pix = pix[slc]
        print 'Sliced pix sum', pix.sum()

        psf = GaussianMixturePSF(fit.amp, fit.mean * scale, fit.var * scale**2)
        psfmodel = psf.getPointSourcePatch(0., 0., radius=h/2)
        mod = psfmodel.patch
        print 'Orig mod sum', mod.sum()
        mod = mod[slc]
        print 'Sliced mod sum', mod.sum()
        print 'Amps:', np.sum(psf.mog.amp)
        
        _plot_psf(pix, mod, psf)
        plt.suptitle('W%i: Orig' % band)
        ps.savefig()
                
        # Lanczos sub-sample
        if band == 4:
            lpix = _lanczos_subsample(opix, 2)
            pix = lpix
            h,w = pix.shape

            #S = 140
            slc = slice(h/2-S, h/2+S+1), slice(w/2-S, w/2+S+1)
            print 'Resampled pix sum', pix.sum()
            pix = pix[slc]
            print 'sliced pix sum', pix.sum()

            psf = GaussianMixturePSF(fit.amp, fit.mean * scale, fit.var * scale**2)
            psfmodel = psf.getPointSourcePatch(0., 0., radius=h/2)
            mod = psfmodel.patch
            print 'Scaled mod sum', mod.sum()
            mod = mod[slc]
            print 'Sliced mod sum', mod.sum()

            _plot_psf(pix, mod, psf)
            plt.suptitle('W%i: Scaled' % band)
            ps.savefig()

            plotslice = slice(S-plotss,-(S-plotss)),slice(S-plotss,-(S-plotss))

        psfx = GaussianMixturePSF.fromStamp(pix, P0=(fit.amp, fit.mean*scale, fit.var*scale**2))
        psfmodel = psfx.getPointSourcePatch(0., 0., radius=h/2)
        mod = psfmodel.patch
        print 'From stamp: mod sum', mod.sum()
        mod = mod[slc]
        print 'Sliced mod sum:', mod.sum()
        _plot_psf(pix, mod, psfx)
        plt.suptitle('W%i: fromStamp: %g = %s, res %.3f' %
                     (band, np.sum(psfx.mog.amp), ','.join(['%.3f'%a for a in psfx.mog.amp]),
                      np.sum(pix - mod)))
        ps.savefig()
        
        print 'Stamp-Fit PSF params:', psfx
    
        # class MyGaussianMixturePSF(GaussianMixturePSF):
        #     def getLogPrior(self):
        #         if np.any(self.mog.amp < 0.):
        #             return -np.inf
        #         for k in range(self.mog.K):
        #             if np.linalg.det(self.mog.var[k]) <= 0:
        #                 return -np.inf
        #         return 0
        # 
        #     @property
        #     def amp(self):
        #         return self.mog.amp
        #     
        # mypsf = MyGaussianMixturePSF(psfx.mog.amp, psfx.mog.mean, psfx.mog.var)
        # mypsf.radius = sh/2


        sh,sw = pix.shape

        # Initialize from original fit params
        psfx = psf
        
        # Try concentric gaussian PSF
        sigmas = []
        for k in range(psfx.mog.K):
            v = psfx.mog.var[k,:,:]
            sigmas.append(np.sqrt(np.sqrt(np.abs(v[0,0] * v[1,1]))))
        print 'Initializing concentric Gaussian PSF with sigmas', sigmas
        gpsf = NCircularGaussianPSF(sigmas, psfx.mog.amp)
        gpsf.radius = sh/2
        mypsf = gpsf
        
        tim = Image(data=pix, invvar=1e6 * np.ones_like(pix), psf=mypsf)
        tim.modelMinval = 1e-16
        
        # xx,yy = np.meshgrid(np.arange(sw), np.arange(sh))
        # cx,cy = np.sum(xx*pix)/np.sum(pix), np.sum(yy*pix)/np.sum(pix)
        # print 'Centroid:', cx,cy
        # print 'Pix midpoint:', sw/2, sh/2
        cx,cy = sw/2, sh/2
        src = PointSource(PixPos(cx, cy), Flux(1.0))
        
        tractor = Tractor([tim], [src])
        
        tim.freezeAllBut('psf')
        #tractor.freezeParam('catalog')
        src.freezeAllBut('pos')
        
        # src.freezeAllBut('brightness')
        # tractor.freezeParam('images')
        # tractor.optimize_forced_photometry()
        # tractor.thawParam('images')
        # print 'Source flux after forced-photom fit:', src.getBrightness()
    
        print 'Optimizing Params:'
        tractor.printThawedParams()
    
        for i in range(200):
            #dlnp,X,alpha = tractor.optimize(damp=0.1)
            dlnp,X,alpha = tractor.optimize(damp=1)
            print i,'dlnp %.3g' % dlnp, 'psf', gpsf
            if dlnp < 1e-6:
                break

        tractor.freezeParam('catalog')
        gpsf.sigmas.stepsize = len(gpsf.sigmas) * [1e-6]
        gpsf.weights.stepsize = len(gpsf.sigmas) * [1e-6]
        
        for i in range(200):
            #dlnp,X,alpha = tractor.optimize(damp=0.1)
            dlnp,X,alpha = tractor.optimize(damp=1)
            print i,'dlnp %.3g' % dlnp, 'psf', gpsf
            if dlnp < 1e-6:
                break

            
        print 'PSF3(opt): flux', src.brightness
        print 'PSF amps:', np.sum(mypsf.amp)
        print 'PSF amps * Source brightness:', src.brightness.getValue() * np.sum(mypsf.amp)
        print 'pix sum:', pix.sum()

        print 'Optimize source:', src
        print 'Optimized PSF:', mypsf
        
        mod = tractor.getModelImage(0)
        print 'Mod sum:', mod.sum()
        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(['%.3f'%a for a in mypsf.amp]), np.sum(pix-mod)))
        ps.savefig()

        # Write before normalizing!
        T = fits_table()
        T.amp  = mypsf.mog.amp
        T.mean = mypsf.mog.mean
        T.var  = mypsf.mog.var
        T.writeto('psf3-w%i.fits' % band)
        T.writeto('psf3.fits', append=(band != 1))
        
        mypsf.weights.setParams(np.array(mypsf.weights.getParams()) /
                                sum(mypsf.weights.getParams()))
        print 'Normalized PSF weights:', mypsf
        mod = tractor.getModelImage(0)
        print 'Mod sum:', mod.sum()
        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(['%.3f'%a for a in mypsf.amp]), np.sum(pix-mod)))
        ps.savefig()


        class MyGaussianPSF(NCircularGaussianPSF):
            '''
            A PSF model with strictly positive weights that sum to
            unity.
            '''
            def __init__(self, sigmas, weights):
                ww = np.array(weights)
                ww = np.log(ww)
                super(MyGaussianPSF, self).__init__(sigmas, ww)

            @staticmethod
            def getNamedParams():
                return dict(sigmas=0, logweights=1)
                
            def __str__(self):
                return ('MyGaussianPSF: sigmas [ ' +
                        ', '.join(['%.3f'%s for s in self.mysigmas]) +
                        ' ], weights [ ' +
                        ', '.join(['%.3f'%w for w in self.myweights]) +
                        ' ]')

            @property
            def myweights(self):
                ww = np.exp(self.logweights.getAllParams())
                ww /= ww.sum()
                return ww

            @property
            def weights(self):
                ww = np.exp(self.logweights.getParams())
                wsum = np.sum(np.exp(self.logweights.getAllParams()))
                return ww / wsum
            

        if band == 4:
            # HACK
            mypsf = MyGaussianPSF([1.7, 6.4, 15.0], [0.333, 0.666, 0.1])
        else:
            mypsf = MyGaussianPSF(gpsf.sigmas, gpsf.amp)
        mypsf.radius = sh/2

        tim.psf = mypsf
        
        print 'Optimizing Params:'
        tractor.printThawedParams()
    
        for i in range(200):
            #dlnp,X,alpha = tractor.optimize(damp=0.1)
            dlnp,X,alpha = tractor.optimize(damp=1)
            print i,'dlnp %.3g' % dlnp, 'psf', mypsf
            if dlnp < 1e-6:
                break

        mypsf.sigmas.stepsize = len(mypsf.sigmas) * [1e-6]
        mypsf.logweights.stepsize = len(mypsf.sigmas) * [1e-6]

        for i in range(200):
            #dlnp,X,alpha = tractor.optimize(damp=0.1)
            dlnp,X,alpha = tractor.optimize(damp=1)
            print i,'dlnp %.3g' % dlnp, 'psf', mypsf
            if dlnp < 1e-6:
                break
        
        print 'PSF amps:', np.sum(mypsf.amp)
        print 'pix sum:', pix.sum()
        print 'Optimize source:', src
        print 'Optimized PSF:', mypsf
        
        mod = tractor.getModelImage(0)
        print 'Mod sum:', mod.sum()
        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt2): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(['%.3f'%a for a in mypsf.amp]), np.sum(pix-mod)))
        ps.savefig()

        # Write
        mog = mypsf.getMixtureOfGaussians()
        T = fits_table()
        T.amp  = mog.amp
        T.mean = mog.mean
        T.var  = mog.var
        T.writeto('psf4.fits', append=(band != 1))
示例#5
0
def _allwise_psf_models():
    global plotslice
    # AllWISE PSF models
    for band in [1,2,3,4]:
        print
        print 'W%i' % band
        print

        pix = reduce(np.add,
                     [fitsio.read('wise-w%i-psf-wpro-09x09-%02ix%02i.fits' %
                                  (band, 1+(i/9), 1+(i%9)))
                                  for i in range(9*9)])
        print 'Pix', pix.shape
        h,w = pix.shape
        print 'Pix sum', pix.sum()
        print 'Pix max', pix.max()
        pix /= pix.sum()
        
        psf = GaussianMixturePSF.fromStamp(pix)
        print 'Fit PSF', psf
        psfmodel = psf.getPointSourcePatch(0., 0., radius=h/2)
        mod = psfmodel.patch
        print 'Orig mod sum', mod.sum()

        S = h/2
        plotss = 30
        plotslice = slice(S-plotss, -(S-plotss)), slice(S-plotss, -(S-plotss))
        
        _plot_psf(pix, mod, psf)
        plt.suptitle('W%i: from stamp' % band)
        ps.savefig()

        # Try concentric gaussian PSF
        sh,sw = pix.shape
        sigmas = []
        for k in range(psf.mog.K):
            v = psf.mog.var[k,:,:]
            sigmas.append(np.sqrt(np.sqrt(v[0,0] * v[1,1])))

        
        print 'Initializing concentric Gaussian model with sigmas', sigmas
        print 'And weights', psf.mog.amp

        # (Initial) W1:
        # sig [7.1729391870564569, 24.098952864976805, 108.78869923786333]
        # weights [ 0.80355109  0.15602835  0.04195982]
        # sigmas [ 6.928, 17.091, 45.745 ], weights [ 0.760, 0.154, 0.073 ]
        
        # W2:
        # sig [8.2356371659198189, 25.741694812001221, 110.17431488810806]
        # weights [ 0.80636191  0.1563742   0.03926182]
        # sigmas [ 7.177, 10.636, 30.247 ], weights [ 0.500, 0.341, 0.134 ]

        # W3:
        # sig [6.860124763919889, 19.160849966251824, 134.20812055907825]
        # weights [ 0.28227047  0.55080156  0.16706357]
        # sigmas [ 6.850, 18.922, 109.121 ], weights [ 0.276, 0.554, 0.148 ]

        # W4:
        # [4.6423676603462001, 5.31542132669962, 18.375512539373585]
        # weights [ 0.10764341  0.26915295  0.62320374]
        # (Opt)
        # sigmas [ 6.293, 6.314, 20.932 ], weights [ 0.129, 0.309, 0.598 ]

        weights = psf.mog.amp

        # HACK
        if band == 4:
            sigmas =  [ 2., 6., 25. ]
            weights = [ 0.5, 0.25, 0.25 ]
        else:
            sigmas =  [ 8., 24., 100. ]
            weights = [ 0.5, 0.25, 0.25 ]
        
        gpsf = NCircularGaussianPSF(sigmas, weights)
        gpsf.radius = sh/2
        mypsf = gpsf
        tim = Image(data=pix, invvar=1e6 * np.ones_like(pix), psf=mypsf)
        cx,cy = sw/2, sh/2
        src = PointSource(PixPos(cx, cy), Flux(1.0))
        
        tractor = Tractor([tim], [src])
        
        tim.freezeAllBut('psf')
        #tractor.freezeParam('catalog')
        src.freezeAllBut('pos')

        print 'Optimizing Params:'
        tractor.printThawedParams()
    
        for i in range(100):
            dlnp,X,alpha = tractor.optimize(damp=0.1)
            print 'dlnp', dlnp
            print 'PSF', mypsf
            if dlnp < 0.001:
                break

        print 'PSF3(opt): flux', src.brightness
        print 'PSF amps:', np.sum(mypsf.amp)
        print 'PSF amps * Source brightness:', src.brightness.getValue() * np.sum(mypsf.amp)
        print 'pix sum:', pix.sum()

        print 'Optimize source:', src
        print 'Optimized PSF:', mypsf
        
        mod = tractor.getModelImage(0)
        print 'Mod sum:', mod.sum()
        print 'Mod min:', mod.min()
        print 'Mod max:', mod.max()

        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(['%.3f'%a for a in mypsf.amp]), np.sum(pix-mod)))
        ps.savefig()


        # These postage stamps are subsampled at 8x the 2.75"/pix,
        # except for the W4 one, which is at 4x that.
        scale = 8
        if band == 4:
            scale = 4
        
        T = fits_table()
        T.amp  = mypsf.mog.amp
        T.mean = mypsf.mog.mean / scale
        T.var  = mypsf.mog.var / scale**2
        T.writeto('psf-allwise-con3-w%i.fits' % band)
        T.writeto('psf-allwise-con3.fits', append=(band != 1))

        
        mypsf.weights.setParams(np.array(mypsf.weights.getParams()) /
                                sum(mypsf.weights.getParams()))
        print 'Normalized PSF weights:', mypsf
        mod = tractor.getModelImage(0)
        print 'Mod sum:', mod.sum()
        _plot_psf(pix, mod, mypsf, flux=src.brightness.getValue())
        plt.suptitle('W%i psf3 (opt): %g = %s, resid %.3f' %
                     (band, np.sum(mypsf.amp), ','.join(['%.3f'%a for a in mypsf.amp]), np.sum(pix-mod)))
        ps.savefig()
示例#6
0
        
    psf2 = GaussianMixturePSF(mypsf.mog.amp[:2]/mypsf.mog.amp[:2].sum(),
                              mypsf.mog.mean[:2,:], mypsf.mog.var[:2,:,:])
    psf2.radius = sh/2
    tim.psf = psf2
    mod = tractor.getModelImage(0)
    _plot_psf(lpix, mod, psf2, flux=src.brightness.getValue())
    plt.suptitle('psf2 (init)')
    ps.savefig()

    src.freezeAllBut('brightness')
    tractor.freezeParam('catalog')
    for i in range(100):

        print 'Optimizing PSF:'
        tractor.printThawedParams()
        
        dlnp,X,alpha = tractor.optimize(damp=1.)

        tractor.freezeParam('images')
        tractor.thawParam('catalog')

        print 'Optimizing flux:'
        tractor.printThawedParams()

        tractor.optimize_forced_photometry()
        tractor.thawParam('images')
        tractor.freezeParam('catalog')
        
    mod = tractor.getModelImage(0)
    _plot_psf(lpix, mod, psf2, flux=src.brightness.getValue())