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))
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()
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())
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))
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()
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())