コード例 #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
ファイル: wise2.py プロジェクト: barentsen/tractor
def simult_photom(cat0=None, WW=None, band=None, tims=None,
				  allrois=None, badrois=None, groups=None,
				  tgroups=None, minsb=None,
				  gslices=None, cat=None,
				  opt=None, ps=None):

	def _plot_grid(ims, kwas):
		N = len(ims)
		C = int(np.ceil(np.sqrt(N)))
		R = int(np.ceil(N / float(C)))
		plt.clf()
		for i,(im,kwa) in enumerate(zip(ims, kwas)):
			plt.subplot(R,C, i+1)
			#print 'plotting grid cell', i, 'img shape', im.shape
			plt.imshow(im, **kwa)
			plt.gray()
			plt.xticks([]); plt.yticks([])
		return R,C

	def _plot_grid2(ims, cat, tims, kwas, ptype='mod'):
		xys = []
		stamps = []
		for (img,mod,chi,roi),tim in zip(ims, tims):
			if ptype == 'mod':
				stamps.append(mod)
			elif ptype == 'chi':
				stamps.append(chi)
			wcs = tim.getWcs()
			y0,x0 = roi[0].start, roi[1].start
			xy = []
			for src in cat:
				xi,yi = wcs.positionToPixel(src.getPosition())
				xy.append((xi - x0, yi - y0))
			xys.append(xy)
			#print 'X,Y source positions in stamp of shape', stamps[-1].shape
			#print '  ', xy
		R,C = _plot_grid(stamps, kwas)
		for i,xy in enumerate(xys):
			plt.subplot(R, C, i+1)
			ax = plt.axis()
			xy = np.array(xy)
			plt.plot(xy[:,0], xy[:,1], 'r+', lw=2)
			plt.axis(ax)

		

	# Simultaneous photometry

	if opt.osources:
		O = fits_table(opt.osources)
		ocat = Catalog()
		print 'Other catalog:'
		for i in range(len(O)):
			w1 = O.wiseflux[i, 0]
			s = PointSource(RaDecPos(O.ra[i], O.dec[i]), NanoMaggies(w1=w1))
			ocat.append(s)
		print ocat
		ocat.freezeParamsRecursive('*')
		ocat.thawPathsTo(band)

	# Keep track of params after simultaneous photometry...
	cat.freezeParamsRecursive('*')
	cat.thawPathsTo(band)
	catsim = cat.getParams()
	if opt.opt:
		# ... and also after RA,Dec opt.
		cat.thawPathsTo('ra','dec')
		catopt = cat.getParams()
		cat.freezeParamsRecursive('*')
		cat.thawPathsTo(band)

	for gi in range(len(gslices)):
		gl = gi
		gl += 1
		if not gl in groups:
			print 'Group', gl, 'not in groups array; skipping'
			continue
		gsrcs = groups[gl]
		tsrcs = tgroups[gl]

		print 'Group', gl
		print 'gsrcs:', gsrcs
		print 'tsrcs:', tsrcs

		if (not gl in allrois) and (not gl in badrois):
			print 'Group', gl, 'does not touch any images?'
			continue

		mytims = []
		rois = []
		if gl in allrois:
			for imi,roi in allrois[gl].items():
				mytims.append(tims[imi])
				rois.append(roi)

		mybadtims = []
		mybadrois = []
		if gl in badrois:
			for imi,roi in badrois[gl].items():
				mybadtims.append(tims[imi])
				mybadrois.append(roi)

		print 'Group', gl, 'touches', len(mytims), 'images and', len(mybadtims), 'bad ones'

		tt = 'group %i: %i+%i sources' % (gl, len(gsrcs), len(tsrcs))

		if len(mytims):

			cat.setParams(catsim)

			#print 'Restoring catsim:'
			#cat.printThawedParams()

			subcat = Catalog(*[cat[i] for i in gsrcs + tsrcs])
			for i in range(len(tsrcs)):
				subcat.freezeParam(len(gsrcs) + i)

			tractor = Tractor(mytims, subcat)
			tractor.freezeParam('images')

			print len(gsrcs), 'sources unfrozen; total', len(subcat)

			print 'Before fitting:'
			for src in subcat[:len(gsrcs)]:
				print '  ', src
				
			t0 = Time()
			ims0,ims1 = tractor.optimize_forced_photometry(minsb=minsb, mindlnp=1.,
														   rois=rois)
			print 'optimize_forced_photometry took', Time()-t0

			print 'After fitting:'
			for src in subcat[:len(gsrcs)]:
				print '  ', src

			imas = [dict(interpolation='nearest', origin='lower',
						 vmin=tim.zr[0], vmax=tim.zr[1])
					for tim in mytims]
			imchi = dict(interpolation='nearest', origin='lower', vmin=-5, vmax=5)
			imchis = [imchi] * len(mytims)

			_plot_grid([img for (img, mod, chi, roi) in ims0], imas)
			plt.suptitle('Data: ' + tt)
			ps.savefig()

			if ims1 is not None:
				#_plot_grid([mod for (img, mod, chi, roi) in ims1], imas)
				_plot_grid2(ims1, subcat, mytims, imas)
				plt.suptitle('Forced-phot model: ' + tt)
				ps.savefig()

				#_plot_grid([chi for (img, mod, chi, roi) in ims1], imchis)
				_plot_grid2(ims1, subcat, mytims, imchis, ptype='chi')
				plt.suptitle('Forced-phot chi: ' + tt)
				ps.savefig()

			if opt.osources:
				cc = tractor.catalog
				tractor.catalog = ocat
				nil,nil,ims3 = tractor.optimize_forced_photometry(minsb=minsb, rois=rois,
																  justims0=True)
				tractor.catalog = cc

				_plot_grid2(ims3, ocat, mytims, imas)
				plt.suptitle("Schlegel's model: group %i" % gl)
				ps.savefig()

				_plot_grid2(ims3, ocat, mytims, imchis, ptype='chi')
				plt.suptitle("Schlegel's chi: group %i" % gl)
				ps.savefig()
				


			if opt.opt:
				op1 = ps.getnext()
				op2 = ps.getnext()
				#fits[gl] = (tractor, len(gsrcs), rois, op1, op2)


			# print 'Plotting mods after simul photom'
			# #_plot_grid([mod for (img, mod, chi, roi) in ims0], imas)
			# _plot_grid2(ims0, subcat, mytims, imas)
			# plt.suptitle('Initial model: ' + tt)
			# ps.savefig()
			# 
			# print 'Plotting chis after simul photom'
			# #_plot_grid([chi for (img, mod, chi, roi) in ims0], imchis)
			# _plot_grid2(ims0, subcat, mytims, imchis, ptype='chi')
			# plt.suptitle('Initial chi: ' + tt)
			# ps.savefig()

			print 'After simultaneous photometry:'
			subcat.printThawedParams()

			# Copy updated params to "catsim"
			catsim = cat.getParams()

			#print 'Saving catsim:'
			#cat.printThawedParams()

			cat.freezeParamsRecursive('*')
			cat.thawPathsTo(band)
			WW.nmall = np.array([src.getBrightness().getBand(band) for src in cat])



		if len(mytims) and opt.opt:
			print 'Optimizing RA,Dec'

			subcat = tractor.catalog

			# Copy updated forced-phot params from catsim to catopt.

			#print 'Saving subcat forced-phot params:'
			#subcat.printThawedParams()
			fphot = subcat.getParams()

			cat.thawPathsTo('ra','dec')
			cat.setParams(catopt)

			#print 'Copying forced-phot results to catopt:'
			cat.freezeParamsRecursive('*')
			cat.thawPathsTo(band)
			cat.freezeAllBut(*gsrcs)
			#cat.printThawedParams()
			NP = cat.numberOfParams()
			cat.setParams(fphot[:NP])
			#print 'Result:'

			#print 'Restoring catopt:'
			#cat.printThawedParams()

			cat.freezeParamsRecursive('*')
			cat.thawPathsTo(band)
			NG = len(gsrcs)
			for i in range(NG):
				subcat[i].thawPathsTo('ra','dec')
			p0 = subcat.getParams()
			print 'Optimizing params:'
			subcat.printThawedParams()

			thetims = tractor.images
			subimgs = []
			for i,img in enumerate(thetims):
				roi = rois[i]
				y0 = roi[0].start
				x0 = roi[1].start
				subwcs = ShiftedWcs(img.wcs, x0, y0)
				subimg = Image(data=img.data[roi], invvar=img.invvar[roi],
							   psf=img.psf, wcs=subwcs, sky=img.sky,
							   photocal=img.photocal, name=img.name)
				subimgs.append(subimg)
			tractor.images = Images(*subimgs)

			while True:
				dlnp,X,alpha = tractor.optimize()
				print 'dlnp', dlnp
				print 'alpha', alpha
				if dlnp < 0.1:
					break

			p1 = subcat.getParams()

			print 'Param changes:'
			for nm,pp0,pp1 in zip(subcat.getParamNames(), p0, p1):
				print '  ', nm, pp0, 'to', pp1, '; delta', pp1-pp0


			cat.thawPathsTo('ra','dec')
			catopt = cat.getParams()

			print 'Saving catopt:'
			cat.printThawedParams()

			cat.freezeParamsRecursive('ra', 'dec')

			tractor.images = thetims

			nil,nil,ims2 = tractor.optimize_forced_photometry(minsb=minsb, rois=rois,
															  justims0=True)

			print 'Plotting mods after RA,Dec opt'
			#_plot_grid([mod for (img, mod, chi, roi) in ims2], imas)
			_plot_grid2(ims2, subcat, mytims, imas)
			plt.suptitle('RA,Dec-opt model: ' + tt)
			plt.savefig(op1)
			
			print 'Plotting chis after RA,Dec opt'
			#_plot_grid([chi for (img, mod, chi, roi) in ims2], imchis)
			_plot_grid2(ims2, subcat, mytims, imchis, ptype='chi')
			plt.suptitle('RA,Dec-opt chi: ' + tt)
			plt.savefig(op2)







		N = len(mybadtims)
		if N and False:
			C = int(np.ceil(np.sqrt(N)))
			R = int(np.ceil(N / float(C)))
			plt.clf()
			for i,(tim,roi) in enumerate(zip(mybadtims, mybadrois)):
				plt.subplot(R,C, i+1)
				plt.imshow(tim.getImage()[roi], interpolation='nearest', origin='lower',
						   vmin=tim.zr[0], vmax=tim.zr[1])
				plt.gray()
			plt.suptitle('Data in bad regions')
			ps.savefig()

			plt.clf()
			for i,(tim,roi) in enumerate(zip(mybadtims, mybadrois)):
				plt.subplot(R,C, i+1)
				plt.imshow(tim.getInvError()[roi], interpolation='nearest', origin='lower')
				plt.gray()
			plt.suptitle('Inverr in bad regions')
			ps.savefig()

		if gi == 0 and opt.plotmask:

			alltims = mybadtims+mytims
			_plot_grid([tim.uncplane[roi] for tim,roi in zip(alltims,
															 mybadrois + rois)],
					   [dict(interpolation='nearest', origin='lower')]*len(alltims))
			plt.suptitle('Uncertainty plane')
			ps.savefig()
	
			for bit,txt in [
				(0 ,  'static: excessively noisy due to high dark current alone'),
				(1 ,  'static: generally noisy [includes bit 0]'),
				(2 ,  'static: dead or very low responsivity'),
				(3 ,  'static: low responsivity or low dark current'),
				(4 ,  'static: high responsivity or high dark current'),
				(5 ,  'static: saturated anywhere in ramp'),
				(6 ,  'static: high, uncertain, or unreliable non-linearity'),
				(7 ,  'static: known broken hardware pixel or excessively noisy responsivity estimate [may include bit 1]'),
				(9 ,  'broken pixel or negative slope fit value'),
				(10,  'saturated in sample read 1'),
				(11,  'saturated in sample read 2'),
				(12,  'saturated in sample read 3'),
				(13,  'saturated in sample read 4'),
				(14,  'saturated in sample read 5'),
				(15,  'saturated in sample read 6'),
				(16,  'saturated in sample read 7'),
				(17,  'saturated in sample read 8'),
				(18,  'saturated in sample read 9'),
				(21,  'new/transient bad pixel from dynamic masking'),
				(26,  'non-linearity correction unreliable'),
				(27,  'contains cosmic-ray or outlier that cannot be classified (from temporal outlier rejection in multi-frame pipeline)'),
				(28,  'contains positive or negative spike-outlier'),
				]:

				_plot_grid([tim.maskplane[roi] & (1 << bit)
							for tim,roi in zip(alltims, mybadrois + rois)],
					   [dict(interpolation='nearest', origin='lower',
							 vmin=0, vmax=1)]*len(alltims))
				plt.suptitle('Mask: ' + txt)
				ps.savefig()



	if opt.opt:

		fn = opt.output % 998
		WW.writeto(fn)
		print 'Wrote', fn

		cat.thawPathsTo('ra','dec')
		cat.setParams(catopt)
		WW.nmoptrd = np.array([src.getBrightness().getBand(band) for src in cat])
		cat.freezeParamsRecursive(band, 'dec')
		WW.raoptrd = np.array(cat.getParams())
		cat.freezeParamsRecursive('ra')
		cat.thawPathsTo('dec')
		WW.decoptrd = np.array(cat.getParams())
		cat.freezeParamsRecursive('dec')

	fn = opt.output % 999
	WW.writeto(fn)
	print 'Wrote', fn
コード例 #3
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()
コード例 #4
0
                              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())
    plt.suptitle('psf2 (opt)')
    ps.savefig()
コード例 #5
0
ファイル: wise_psf.py プロジェクト: barentsen/tractor
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))
コード例 #6
0
ファイル: wise_psf.py プロジェクト: barentsen/tractor
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()
コード例 #7
0
ファイル: wise_psf.py プロジェクト: barentsen/tractor
                              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())
    plt.suptitle('psf2 (opt)')
    ps.savefig()