def galaxy_norm(self, tim, x=None, y=None): # Galaxy-detection norm from tractor.galaxy import ExpGalaxy from tractor.ellipses import EllipseE from tractor.patch import ModelMask h, w = tim.shape band = tim.band if x is None: x = w / 2. if y is None: y = h / 2. pos = tim.wcs.pixelToPosition(x, y) gal = SimpleGalaxy(pos, NanoMaggies(**{band: 1.})) S = 32 mm = ModelMask(int(x - S), int(y - S), 2 * S + 1, 2 * S + 1) galmod = gal.getModelPatch(tim, modelMask=mm).patch galmod = np.maximum(0, galmod) galmod /= galmod.sum() galnorm = np.sqrt(np.sum(galmod**2)) return galnorm
def psf_residuals(expnum, ccdname, stampsize=35, nstar=30, magrange=(13, 17), verbose=0, splinesky=False): # Set the debugging level. if verbose == 0: lvl = logging.INFO else: lvl = logging.DEBUG logging.basicConfig(level=lvl, format='%(message)s', stream=sys.stdout) pngprefix = 'qapsf-{}-{}'.format(expnum, ccdname) # Gather all the info we need about this CCD. decals = Decals() ccd = decals.find_ccds(expnum=expnum, ccdname=ccdname)[0] band = ccd.filter ps1band = dict(g=0, r=1, i=2, z=3, Y=4) print('Band {}'.format(band)) #scales = dict(g=0.0066, r=0.01, z=0.025) #vmin, vmax = np.arcsinh(-1), np.arcsinh(100) #print(scales[band]) im = decals.get_image_object(ccd) iminfo = im.get_image_info() H, W = iminfo['dims'] wcs = im.get_wcs() # Choose a uniformly selected subset of PS1 stars on this CCD. ps1 = ps1cat(ccdwcs=wcs) cat = ps1.get_stars(band=band, magrange=magrange) rand = np.random.RandomState(seed=expnum * ccd.ccdnum) these = rand.choice(len(cat) - 1, nstar, replace=False) #these = rand.random_integers(0,len(cat)-1,nstar) cat = cat[these] cat = cat[np.argsort(cat.median[:, ps1band[band]])] # sort by magnitude #print(cat.nmag_ok) get_tim_kwargs = dict(const2psf=True, splinesky=splinesky) # Make a QAplot of the positions of all the stars. tim = im.get_tractor_image(**get_tim_kwargs) img = tim.getImage() #img = tim.getImage()/scales[band] fig = plt.figure(figsize=(5, 10)) ax = fig.gca() ax.get_xaxis().get_major_formatter().set_useOffset(False) #ax.imshow(np.arcsinh(img),cmap='gray',interpolation='nearest', # origin='lower',vmin=vmax,vmax=vmax) ax.imshow(img, **tim.ima) ax.axis('off') ax.set_title('{}: {}/{} AM={:.2f} Seeing={:.3f}"'.format( band, expnum, ccdname, ccd.airmass, ccd.seeing)) for istar, ps1star in enumerate(cat): ra, dec = (ps1star.ra, ps1star.dec) ok, xpos, ypos = wcs.radec2pixelxy(ra, dec) ax.text(xpos, ypos, '{:2d}'.format(istar + 1), color='red', horizontalalignment='left') circ = plt.Circle((xpos, ypos), radius=30, color='g', fill=False, lw=1) ax.add_patch(circ) #radec = wcs.radec_bounds() #ax.scatter(cat.ra,cat.dec) #ax.set_xlim([radec[1],radec[0]])#*[1.0002,0.9998]) #ax.set_ylim([radec[2],radec[3]])#*[0.985,1.015]) #ax.set_xlabel('$RA\ (deg)$',fontsize=18) #ax.set_ylabel('$Dec\ (deg)$',fontsize=18) fig.savefig(pngprefix + '-ccd.png', bbox_inches='tight') # Initialize the many-stamp QAplot ncols = 3 nrows = np.ceil(nstar / ncols).astype('int') inchperstamp = 2.0 fig = plt.figure(figsize=(inchperstamp * 3 * ncols, inchperstamp * nrows)) irow = 0 icol = 0 for istar, ps1star in enumerate(cat): ra, dec = (ps1star.ra, ps1star.dec) mag = ps1star.median[ps1band[band]] # r-band ok, xpos, ypos = wcs.radec2pixelxy(ra, dec) ix, iy = int(xpos), int(ypos) # create a little tractor Image object around the star slc = (slice(max(iy - stampsize, 0), min(iy + stampsize + 1, H)), slice(max(ix - stampsize, 0), min(ix + stampsize + 1, W))) # The PSF model 'const2Psf' is the one used in DR1: a 2-component # Gaussian fit to PsfEx instantiated in the image center. tim = im.get_tractor_image(slc=slc, **get_tim_kwargs) stamp = tim.getImage() ivarstamp = tim.getInvvar() # Initialize a tractor PointSource from PS1 measurements flux = NanoMaggies.magToNanomaggies(mag) star = PointSource(RaDecPos(ra, dec), NanoMaggies(**{band: flux})) # Fit just the source RA,Dec,flux. tractor = Tractor([tim], [star]) tractor.freezeParam('images') print('2-component MOG:', tim.psf) tractor.printThawedParams() for step in range(50): dlnp, X, alpha = tractor.optimize() if dlnp < 0.1: break print('Fit:', star) model_mog = tractor.getModelImage(0) chi2_mog = -2.0 * tractor.getLogLikelihood() mag_mog = NanoMaggies.nanomaggiesToMag(star.brightness)[0] # Now change the PSF model to a pixelized PSF model from PsfEx instantiated # at this place in the image. psf = PixelizedPsfEx(im.psffn) tim.psf = psf.constantPsfAt(xpos, ypos) #print('PSF model:', tim.psf) #tractor.printThawedParams() for step in range(50): dlnp, X, alpha = tractor.optimize() if dlnp < 0.1: break print('Fit:', star) model_psfex = tractor.getModelImage(0) chi2_psfex = -2.0 * tractor.getLogLikelihood() mag_psfex = NanoMaggies.nanomaggiesToMag(star.brightness)[0] #mn, mx = np.percentile((stamp-model_psfex)[ivarstamp>0],[1,95]) sig = np.std((stamp - model_psfex)[ivarstamp > 0]) mn, mx = [-2.0 * sig, 5 * sig] # Generate a QAplot. if (istar > 0) and (istar % (ncols) == 0): irow = irow + 1 icol = 3 * istar - 3 * ncols * irow #print(istar, irow, icol, icol+1, icol+2) ax1 = plt.subplot2grid((nrows, 3 * ncols), (irow, icol), aspect='equal') ax1.axis('off') #ax1.imshow(stamp, **tim.ima) ax1.imshow(stamp, cmap='gray', interpolation='nearest', origin='lower', vmin=mn, vmax=mx) ax1.text(0.1, 0.9, '{:2d}'.format(istar + 1), color='white', horizontalalignment='left', verticalalignment='top', transform=ax1.transAxes) ax2 = plt.subplot2grid((nrows, 3 * ncols), (irow, icol + 1), aspect='equal') ax2.axis('off') #ax2.imshow(stamp-model_mog, **tim.ima) ax2.imshow(stamp - model_mog, cmap='gray', interpolation='nearest', origin='lower', vmin=mn, vmax=mx) ax2.text(0.1, 0.9, 'MoG', color='white', horizontalalignment='left', verticalalignment='top', transform=ax2.transAxes) ax2.text(0.08, 0.08, '{:.3f}'.format(mag_mog), color='white', horizontalalignment='left', verticalalignment='bottom', transform=ax2.transAxes) #ax2.set_title('{:.3f}, {:.2f}'.format(mag_psfex,chi2_psfex),fontsize=14) #ax2.set_title('{:.3f}, $\chi^{2}$={:.2f}'.format(mag_psfex,chi2_psfex)) ax3 = plt.subplot2grid((nrows, 3 * ncols), (irow, icol + 2), aspect='equal') ax3.axis('off') #ax3.imshow(stamp-model_psfex, **tim.ima) ax3.imshow(stamp - model_psfex, cmap='gray', interpolation='nearest', origin='lower', vmin=mn, vmax=mx) ax3.text(0.1, 0.9, 'PSFEx', color='white', horizontalalignment='left', verticalalignment='top', transform=ax3.transAxes) ax3.text(0.08, 0.08, '{:.3f}'.format(mag_psfex), color='white', horizontalalignment='left', verticalalignment='bottom', transform=ax3.transAxes) if istar == (nstar - 1): break fig.savefig(pngprefix + '-stargrid.png', bbox_inches='tight')
def run_sed_matched_filters(SEDs, bands, detmaps, detivs, omit_xy, targetwcs, nsigma=5, saturated_pix=None, plots=False, ps=None, mp=None): ''' Runs a given set of SED-matched filters. Parameters ---------- SEDs : list of (name, sed) tuples The SEDs to run. The `sed` values are lists the same length as `bands`. bands : list of string The band names of `detmaps` and `detivs`. detmaps : numpy array, float Detection maps for each of the listed `bands`. detivs : numpy array, float Inverse-variances of the `detmaps`. omit_xy : None, or (xx,yy) tuple Existing sources to avoid. targetwcs : WCS object WCS object to use to convert pixel values into RA,Decs for the returned Tractor PointSource objects. nsigma : float, optional Detection threshold saturated_pix : None or numpy array, boolean Passed through to sed_matched_detection. A map of pixels that are always considered "hot" when determining whether a new source touches hot pixels of an existing source. plots : boolean, optional Create plots? ps : PlotSequence object Create plots? mp : multiproc object Multiprocessing Returns ------- Tnew : fits_table Table of new sources detected newcat : list of PointSource objects Newly detected objects, with positions and fluxes, as Tractor PointSource objects. hot : numpy array of bool "Hot pixels" containing sources. See also -------- sed_matched_detection : run a single SED-matched filter. ''' if omit_xy is not None: xx, yy = omit_xy n0 = len(xx) else: xx, yy = [], [] n0 = 0 H, W = detmaps[0].shape hot = np.zeros((H, W), bool) peaksn = [] apsn = [] for sedname, sed in SEDs: print('SED', sedname) if plots: pps = ps else: pps = None t0 = Time() sedhot, px, py, peakval, apval = sed_matched_detection( sedname, sed, detmaps, detivs, bands, xx, yy, nsigma=nsigma, saturated_pix=saturated_pix, ps=pps) print('SED took', Time() - t0) if sedhot is None: continue print(len(px), 'new peaks') hot |= sedhot # With an empty xx, np.append turns it into a double! xx = np.append(xx, px).astype(int) yy = np.append(yy, py).astype(int) peaksn.extend(peakval) apsn.extend(apval) # New peaks: peakx = xx[n0:] peaky = yy[n0:] if len(peakx) == 0: return None, None, None # Add sources for the new peaks we found pr, pd = targetwcs.pixelxy2radec(peakx + 1, peaky + 1) print('Adding', len(pr), 'new sources') # Also create FITS table for new sources Tnew = fits_table() Tnew.ra = pr Tnew.dec = pd Tnew.tx = peakx Tnew.ty = peaky assert (len(peaksn) == len(Tnew)) assert (len(apsn) == len(Tnew)) Tnew.peaksn = np.array(peaksn) Tnew.apsn = np.array(apsn) Tnew.itx = np.clip(np.round(Tnew.tx), 0, W - 1).astype(int) Tnew.ity = np.clip(np.round(Tnew.ty), 0, H - 1).astype(int) newcat = [] for i, (r, d, x, y) in enumerate(zip(pr, pd, peakx, peaky)): fluxes = dict([(band, detmap[Tnew.ity[i], Tnew.itx[i]]) for band, detmap in zip(bands, detmaps)]) newcat.append( PointSource(RaDecPos(r, d), NanoMaggies(order=bands, **fluxes))) return Tnew, newcat, hot
return I if __name__ == '__main__': #(allp, i2magsA, cat) = unpickle_from_file('s2-260-A.pickle') (allp, i2mags, cat) = unpickle_from_file('s2-382.pickle') #print 'i2 mags A:', len(i2magsA) #print 'i2 mags:', len(i2mags) #i2mags = i2magsA from tractor.basics import NanoMaggies #print 'i2mags', i2mags i2mags = np.array([NanoMaggies(i=m).getMag('i') for m in i2mags]) #print 'i2mags', mags #allbands = ['i2','u','g','r','i','z'] allbands = ['i2', 'u', 'g', 'r', 'i', 'z', 'w1', 'w2', 'w3', 'w4'] T = fits_table('cs82data/W4p1m1_i.V2.7A.swarp.cut.deVexp.fit', hdunum=2) #RA = 334.32 #DEC = 0.315 #sz = 0.12 * 3600. #S = sz / 3600. #ra0 ,ra1 = RA-S/2., RA+S/2. #dec0,dec1 = DEC-S/2., DEC+S/2. print 'Read', len(T), 'sources' T.ra = T.alpha_j2000 T.dec = T.delta_j2000