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))
tim = galex_read_image(gbase + tag, band=band, radecroi=rdroi) #print '200,500', tim.getWcs().pixelToPosition(200,500) #print '250,550', tim.getWcs().pixelToPosition(250,550) tractor = Tractor([tim], cat) print 'Created', tractor # ima = dict(interpolation='nearest', origin='lower', vmin=tim.zr[0], vmax=tim.zr[1]) #ima = dict(interpolation='nearest', origin='upper', vmin=0, vmax=0.1) ima = dict(interpolation='nearest', origin='upper', vmin=0, vmax=0.03) im = tim.getImage() print 'Image range:', im.min(), im.max() plt.clf() plt.imshow(tim.getImage(), **ima) plt.gray() #plt.colorbar() #plt.title(tim.name + ': data') ps.savefig() mod = tractor.getModelImage(0) plt.clf() plt.imshow(mod, **ima) plt.gray() #plt.colorbar() #plt.title(tim.name + ': model') ps.savefig()
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()
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()
ps.savefig() #_meisner_psf_models() sys.exit(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('Cut to', len(T), 'within RA,Dec box') srcs, isrcs = get_cs82_sources(T, bands=['i']) print('Got', len(srcs), 'sources') Ti = T[isrcs] tim = Image(data=np.zeros((H, W), np.float32), invvar=np.ones((H, W), np.float32), psf=medpsf, wcs=ConstantFitsWcs(wcs), sky=ConstantSky(0.), photocal=LinearPhotoCal(1., band=band), domask=False) tractor = Tractor([tim], srcs) mod = tractor.getModelImage(0) plt.clf() plt.imshow(mod, **coa) gridlines() setRadecAxes(r0, r1, d0, d1) plt.title('CS82 catalog model') ps.savefig() #ras = [src.pos.ra for src in srcs] #I,J,d = match_radec(ras, [src.pos.dec for src in srcs], # T1.ra, T1.dec, 1./3600.) I, J, d = match_radec(Ti.ra, Ti.dec, T1.ra, T1.dec, 1. / 3600.) print('CS82:', len(Ti), 'and matched', len(I)) nm = T1.sdss_i_nanomaggies for i, j in zip(I, J):
tr.printThawedParams() tr.optimize_loop() ## print('Fit:', src) # Take several linearized least squares steps. for i in range(20): dlnp, X, alpha = tr.optimize() print('dlnp', dlnp) if dlnp < 1e-3: break # Plot optimized models. mods = [tractor.getModelImage(i) for i in range(len(tims))] plt.clf() for i, band in enumerate(bands): for e in range(nepochs): plt.subplot(nepochs, len(bands), e * len(bands) + i + 1) plt.imshow(mods[nepochs * i + e], **ima) plt.xticks([]) plt.yticks([]) plt.title('%s #%i' % (band, e + 1)) plt.suptitle('Optimized models') plt.savefig('opt.png') # Plot optimized models + noise: plt.clf() for i, band in enumerate(bands):
def forcedphot(): T1 = fits_table('cs82data/cas-primary-DR8.fits') print(len(T1), 'primary') T1.cut(T1.nchild == 0) print(len(T1), 'children') rl, rh = T1.ra.min(), T1.ra.max() dl, dh = T1.dec.min(), T1.dec.max() tims = [] # Coadd basedir = os.path.join('cs82data', 'wise', 'level3') basefn = os.path.join(basedir, '3342p000_ab41-w1') tim = read_wise_coadd(basefn, radecroi=[rl, rh, dl, dh], nanomaggies=True) tims.append(tim) # Individuals basedir = os.path.join('cs82data', 'wise', 'level1b') for fn in ['04933b137-w1', '04937b137-w1', '04941b137-w1', '04945b137-w1', '04948a112-w1', '04949b137-w1', '04952a112-w1', '04953b137-w1', '04956a112-w1', '04960a112-w1', '04964a112-w1', '04968a112-w1', '05204a106-w1']: basefn = os.path.join(basedir, fn) tim = read_wise_image( basefn, radecroi=[rl, rh, dl, dh], nanomaggies=True) tims.append(tim) # tractor.Image's setMask() does a binary dilation on bad pixels! for tim in tims: # tim.mask = np.zeros(tim.shape, dtype=bool) tim.invvar = tim.origInvvar tim.mask = np.zeros(tim.shape, dtype=bool) print('tim:', tim) ps = PlotSequence('forced') plt.clf() plt.plot(T1.ra, T1.dec, 'r.') for tim in tims: wcs = tim.getWcs() H, W = tim.shape rr, dd = [], [] for x, y in zip([1, 1, W, W, 1], [1, H, H, 1, 1]): rd = wcs.pixelToPosition(x, y) rr.append(rd.ra) dd.append(rd.dec) plt.plot(rr, dd, 'k-', alpha=0.5) # setRadecAxes(rl,rh,dl,dh) ps.savefig() T2 = fits_table('wise-cut.fits') T2.w1 = T2.w1mpro R = 1. / 3600. I, J, d = match_radec(T1.ra, T1.dec, T2.ra, T2.dec, R) print(len(I), 'matches') refband = 'r' #bandnum = band_index('r') Lstar = (T1.probpsf == 1) * 1.0 Lgal = (T1.probpsf == 0) fracdev = T1.get('fracdev_%s' % refband) Ldev = Lgal * fracdev Lexp = Lgal * (1. - fracdev) ndev, nexp, ncomp, nstar = 0, 0, 0, 0 cat = Catalog() # for i,t in enumerate(T1): jmatch = np.zeros(len(T1)) jmatch[:] = -1 jmatch[I] = J for i in range(len(T1)): j = jmatch[i] if j >= 0: # match source: grab WISE catalog mag w1 = T2.w1[j] else: # unmatched: set it faint w1 = 18. bright = NanoMaggies(w1=NanoMaggies.magToNanomaggies(w1)) pos = RaDecPos(T1.ra[i], T1.dec[i]) if Lstar[i] > 0: # Star star = PointSource(pos, bright) cat.append(star) nstar += 1 continue hasdev = (Ldev[i] > 0) hasexp = (Lexp[i] > 0) iscomp = (hasdev and hasexp) if iscomp: dbright = bright * Ldev[i] ebright = bright * Lexp[i] elif hasdev: dbright = bright elif hasexp: ebright = bright else: assert(False) if hasdev: re = T1.get('devrad_%s' % refband)[i] ab = T1.get('devab_%s' % refband)[i] phi = T1.get('devphi_%s' % refband)[i] dshape = GalaxyShape(re, ab, phi) if hasexp: re = T1.get('exprad_%s' % refband)[i] ab = T1.get('expab_%s' % refband)[i] phi = T1.get('expphi_%s' % refband)[i] eshape = GalaxyShape(re, ab, phi) if iscomp: gal = CompositeGalaxy(pos, ebright, eshape, dbright, dshape) ncomp += 1 elif hasdev: gal = DevGalaxy(pos, dbright, dshape) ndev += 1 elif hasexp: gal = ExpGalaxy(pos, ebright, eshape) nexp += 1 cat.append(gal) print('Created', ndev, 'pure deV', nexp, 'pure exp and', end=' ') print(ncomp, 'composite galaxies', end=' ') print('and', nstar, 'stars') tractor = Tractor(tims, cat) for i, tim in enumerate(tims): ima = dict(interpolation='nearest', origin='lower', vmin=tim.zr[0], vmax=tim.zr[1]) mod = tractor.getModelImage(i) plt.clf() plt.imshow(mod, **ima) plt.gray() plt.title('model: %s' % tim.name) ps.savefig() plt.clf() plt.imshow(tim.getImage(), **ima) plt.gray() plt.title('data: %s' % tim.name) ps.savefig() plt.clf() plt.imshow(tim.getInvvar(), interpolation='nearest', origin='lower') plt.gray() plt.title('invvar') ps.savefig() # for tim in tims: wcs = tim.getWcs() H, W = tim.shape poly = [] for r, d in zip([rl, rl, rh, rh, rl], [dl, dh, dh, dl, dl]): x, y = wcs.positionToPixel(RaDecPos(r, d)) poly.append((x, y)) xx, yy = np.meshgrid(np.arange(W), np.arange(H)) xy = np.vstack((xx.flat, yy.flat)).T grid = points_inside_poly(xy, poly) grid = grid.reshape((H, W)) tim.setInvvar(tim.getInvvar() * grid) # plt.clf() # plt.imshow(grid, interpolation='nearest', origin='lower') # plt.gray() # ps.savefig() plt.clf() plt.imshow(tim.getInvvar(), interpolation='nearest', origin='lower') plt.gray() plt.title('invvar') ps.savefig() if i == 1: plt.clf() plt.imshow(tim.goodmask, interpolation='nearest', origin='lower') plt.gray() plt.title('goodmask') ps.savefig() miv = (1. / (tim.uncplane)**2) for bit in range(-1, 32): if bit >= 0: miv[(tim.maskplane & (1 << bit)) != 0] = 0. if bit == 31: plt.clf() plt.imshow(miv, interpolation='nearest', origin='lower') plt.gray() plt.title( 'invvar with mask bits up to %i blanked out' % bit) ps.savefig()