def run_calibs(self, psfex=True, sky=True, funpack=False, git_version=None, force=False, **kwargs): from astrometry.util.file import trymakedirs from legacypipe.common import (create_temp, get_version_header, get_git_version) print('run_calibs for', self.name, ': sky=', sky, 'kwargs', kwargs) se = False if psfex and os.path.exists(self.psffn) and (not force): psfex = False if psfex: se = True if se and os.path.exists(self.sefn) and (not force): se = False if se: funpack = True if sky and (not force) and os.path.exists(self.splineskyfn): sky = False tmpimgfn = None tmpmaskfn = None # Unpacked image file funimgfn = self.imgfn funmaskfn = self.dqfn if funpack: # For FITS files that are not actually fpack'ed, funpack -E # fails. Check whether actually fpacked. hdr = fitsio.read_header(self.imgfn, ext=self.hdu) if not ((hdr['XTENSION'] == 'BINTABLE') and hdr.get('ZIMAGE', False)): print( 'Image', self.imgfn, 'HDU', self.hdu, 'is not actually fpacked; not funpacking, just imcopying.') fcopy = True tmpimgfn = create_temp(suffix='.fits') tmpmaskfn = create_temp(suffix='.fits') cmd = 'funpack -E %i -O %s %s' % (self.hdu, tmpimgfn, self.imgfn) print(cmd) if os.system(cmd): raise RuntimeError('Command failed: ' + cmd) funimgfn = tmpimgfn cmd = 'funpack -E %i -O %s %s' % (self.hdu, tmpmaskfn, self.dqfn) print(cmd) if os.system(cmd): print('Command failed: ' + cmd) M, hdr = self._read_fits(self.dqfn, ext=self.hdu, header=True) print('Read', M.dtype, M.shape) fitsio.write(tmpmaskfn, M, header=hdr, clobber=True) print('Wrote', tmpmaskfn, 'with fitsio') funmaskfn = tmpmaskfn if se: # grab header values... primhdr = self.read_image_primary_header() magzp = primhdr['MAGZERO'] seeing = self.pixscale * self.fwhm print('FWHM', self.fwhm, 'pix') print('pixscale', self.pixscale, 'arcsec/pix') print('Seeing', seeing, 'arcsec') if se: maskstr = '-FLAG_IMAGE ' + funmaskfn sedir = self.decals.get_se_dir() trymakedirs(self.sefn, dir=True) cmd = ' '.join([ 'sex', '-c', os.path.join(sedir, 'DECaLS.se'), maskstr, '-SEEING_FWHM %f' % seeing, '-PARAMETERS_NAME', os.path.join(sedir, 'DECaLS.param'), '-FILTER_NAME', os.path.join(sedir, 'gauss_5.0_9x9.conv'), '-STARNNW_NAME', os.path.join(sedir, 'default.nnw'), '-PIXEL_SCALE 0', # SE has a *bizarre* notion of "sigma" '-DETECT_THRESH 1.0', '-ANALYSIS_THRESH 1.0', '-MAG_ZEROPOINT %f' % magzp, '-CATALOG_NAME', self.sefn, funimgfn ]) print(cmd) if os.system(cmd): raise RuntimeError('Command failed: ' + cmd) if psfex: sedir = self.decals.get_se_dir() trymakedirs(self.psffn, dir=True) # If we wrote *.psf instead of *.fits in a previous run... oldfn = self.psffn.replace('.fits', '.psf') if os.path.exists(oldfn): print('Moving', oldfn, 'to', self.psffn) os.rename(oldfn, self.psffn) else: primhdr = self.read_image_primary_header() plver = primhdr.get('PLVER', '') verstr = get_git_version() cmds = [ 'psfex -c %s -PSF_DIR %s %s' % (os.path.join(sedir, 'DECaLS.psfex'), os.path.dirname(self.psffn), self.sefn), 'modhead %s LEGPIPEV %s "legacypipe git version"' % (self.psffn, verstr), 'modhead %s PLVER %s "CP ver of image file"' % (self.psffn, plver) ] for cmd in cmds: print(cmd) rtn = os.system(cmd) if rtn: raise RuntimeError('Command failed: ' + cmd + ': return value: %i' % rtn) if sky: #print('Fitting sky for', self) hdr = get_version_header(None, self.decals.get_decals_dir(), git_version=git_version) primhdr = self.read_image_primary_header() plver = primhdr.get('PLVER', '') hdr.delete('PROCTYPE') hdr.add_record( dict(name='PROCTYPE', value='ccd', comment='NOAO processing type')) hdr.add_record( dict(name='PRODTYPE', value='skymodel', comment='NOAO product type')) hdr.add_record( dict(name='PLVER', value=plver, comment='CP ver of image file')) slc = self.get_good_image_slice(None) #print('Good image slice is', slc) img = self.read_image(slice=slc) wt = self.read_invvar(slice=slc) from tractor.splinesky import SplineSky from scipy.ndimage.morphology import binary_dilation # Start by subtracting the overall median med = np.median(img[wt > 0]) # Compute initial model... skyobj = SplineSky.BlantonMethod(img - med, wt > 0, 512) skymod = np.zeros_like(img) skyobj.addTo(skymod) # Now mask bright objects in (image - initial sky model) sig1 = 1. / np.sqrt(np.median(wt[wt > 0])) masked = (img - med - skymod) > (5. * sig1) masked = binary_dilation(masked, iterations=3) masked[wt == 0] = True # Now find the final sky model using that more extensive mask skyobj = SplineSky.BlantonMethod(img - med, np.logical_not(masked), 512) # add the median back in skyobj.offset(med) if slc is not None: sy, sx = slc y0 = sy.start x0 = sx.start skyobj.shift(-x0, -y0) trymakedirs(self.splineskyfn, dir=True) skyobj.write_fits(self.splineskyfn, primhdr=hdr) print('Wrote sky model', self.splineskyfn) if tmpimgfn is not None: os.unlink(tmpimgfn) if tmpmaskfn is not None: os.unlink(tmpmaskfn)
def main(decals=None, opt=None): '''Driver function for forced photometry of individual DECam images. ''' if opt is None: parser = get_parser() opt = parser.parse_args() Time.add_measurement(MemMeas) t0 = Time() if os.path.exists(opt.outfn): print('Ouput file exists:', opt.outfn) sys.exit(0) if not opt.forced: opt.apphot = True zoomslice = None if opt.zoom is not None: (x0,x1,y0,y1) = opt.zoom zoomslice = (slice(y0,y1), slice(x0,x1)) ps = None if opt.plots is not None: from astrometry.util.plotutils import PlotSequence ps = PlotSequence(opt.plots) # Try parsing filename as exposure number. try: expnum = int(opt.filename) opt.filename = None except: # make this 'None' for decals.find_ccds() expnum = None # Try parsing HDU number try: opt.hdu = int(opt.hdu) ccdname = None except: ccdname = opt.hdu opt.hdu = -1 if decals is None: decals = Decals() if opt.filename is not None and opt.hdu >= 0: # Read metadata from file T = exposure_metadata([opt.filename], hdus=[opt.hdu]) print('Metadata:') T.about() else: # Read metadata from decals-ccds.fits table T = decals.find_ccds(expnum=expnum, ccdname=ccdname) print(len(T), 'with expnum', expnum, 'and CCDname', ccdname) if opt.hdu >= 0: T.cut(T.image_hdu == opt.hdu) print(len(T), 'with HDU', opt.hdu) if opt.filename is not None: T.cut(np.array([f.strip() == opt.filename for f in T.image_filename])) print(len(T), 'with filename', opt.filename) assert(len(T) == 1) im = decals.get_image_object(T[0]) tim = im.get_tractor_image(slc=zoomslice, pixPsf=True, splinesky=True) print('Got tim:', tim) if opt.catfn in ['DR1', 'DR2']: if opt.catalog_path is None: opt.catalog_path = opt.catfn.lower() margin = 20 TT = [] chipwcs = tim.subwcs bricks = bricks_touching_wcs(chipwcs, decals=decals) for b in bricks: # there is some overlap with this brick... read the catalog. fn = os.path.join(opt.catalog_path, 'tractor', b.brickname[:3], 'tractor-%s.fits' % b.brickname) if not os.path.exists(fn): print('WARNING: catalog', fn, 'does not exist. Skipping!') continue print('Reading', fn) T = fits_table(fn) ok,xx,yy = chipwcs.radec2pixelxy(T.ra, T.dec) W,H = chipwcs.get_width(), chipwcs.get_height() I = np.flatnonzero((xx >= -margin) * (xx <= (W+margin)) * (yy >= -margin) * (yy <= (H+margin))) T.cut(I) print('Cut to', len(T), 'sources within image + margin') # print('Brick_primary:', np.unique(T.brick_primary)) T.cut(T.brick_primary) print('Cut to', len(T), 'on brick_primary') T.cut((T.out_of_bounds == False) * (T.left_blob == False)) print('Cut to', len(T), 'on out_of_bounds and left_blob') TT.append(T) T = merge_tables(TT) T._header = TT[0]._header del TT # Fix up various failure modes: # FixedCompositeGalaxy(pos=RaDecPos[240.51147402832561, 10.385488075518923], brightness=NanoMaggies: g=(flux -2.87), r=(flux -5.26), z=(flux -7.65), fracDev=FracDev(0.60177207), shapeExp=re=3.78351e-44, e1=9.30367e-13, e2=1.24392e-16, shapeDev=re=inf, e1=-0, e2=-0) # -> convert to EXP I = np.flatnonzero(np.array([((t.type == 'COMP') and (not np.isfinite(t.shapedev_r))) for t in T])) if len(I): print('Converting', len(I), 'bogus COMP galaxies to EXP') for i in I: T.type[i] = 'EXP' # Same thing with the exp component. # -> convert to DEV I = np.flatnonzero(np.array([((t.type == 'COMP') and (not np.isfinite(t.shapeexp_r))) for t in T])) if len(I): print('Converting', len(I), 'bogus COMP galaxies to DEV') for i in I: T.type[i] = 'DEV' if opt.write_cat: T.writeto(opt.write_cat) print('Wrote catalog to', opt.write_cat) else: T = fits_table(opt.catfn) T.shapeexp = np.vstack((T.shapeexp_r, T.shapeexp_e1, T.shapeexp_e2)).T T.shapedev = np.vstack((T.shapedev_r, T.shapedev_e1, T.shapedev_e2)).T cat = read_fits_catalog(T, ellipseClass=tractor.ellipses.EllipseE) # print('Got cat:', cat) print('Forced photom...') opti = None if opt.ceres: from tractor.ceres_optimizer import CeresOptimizer B = 8 opti = CeresOptimizer(BW=B, BH=B) tr = Tractor([tim], cat, optimizer=opti) tr.freezeParam('images') for src in cat: src.freezeAllBut('brightness') src.getBrightness().freezeAllBut(tim.band) F = fits_table() F.brickid = T.brickid F.brickname = T.brickname F.objid = T.objid F.filter = np.array([tim.band] * len(T)) F.mjd = np.array([tim.primhdr['MJD-OBS']] * len(T)) F.exptime = np.array([tim.primhdr['EXPTIME']] * len(T)) ok,x,y = tim.sip_wcs.radec2pixelxy(T.ra, T.dec) F.x = (x-1).astype(np.float32) F.y = (y-1).astype(np.float32) if opt.apphot: import photutils img = tim.getImage() ie = tim.getInvError() with np.errstate(divide='ignore'): imsigma = 1. / ie imsigma[ie == 0] = 0. apimg = [] apimgerr = [] # Aperture photometry locations xxyy = np.vstack([tim.wcs.positionToPixel(src.getPosition()) for src in cat]).T apxy = xxyy - 1. apertures = apertures_arcsec / tim.wcs.pixel_scale() print('Apertures:', apertures, 'pixels') for rad in apertures: aper = photutils.CircularAperture(apxy, rad) p = photutils.aperture_photometry(img, aper, error=imsigma) apimg.append(p.field('aperture_sum')) apimgerr.append(p.field('aperture_sum_err')) ap = np.vstack(apimg).T ap[np.logical_not(np.isfinite(ap))] = 0. F.apflux = ap ap = 1./(np.vstack(apimgerr).T)**2 ap[np.logical_not(np.isfinite(ap))] = 0. F.apflux_ivar = ap if opt.forced: kwa = {} if opt.plots is None: kwa.update(wantims=False) R = tr.optimize_forced_photometry(variance=True, fitstats=True, shared_params=False, **kwa) if opt.plots: (data,mod,ie,chi,roi) = R.ims1[0] ima = tim.ima imchi = dict(interpolation='nearest', origin='lower', vmin=-5, vmax=5) plt.clf() plt.imshow(data, **ima) plt.title('Data: %s' % tim.name) ps.savefig() plt.clf() plt.imshow(mod, **ima) plt.title('Model: %s' % tim.name) ps.savefig() plt.clf() plt.imshow(chi, **imchi) plt.title('Chi: %s' % tim.name) ps.savefig() F.flux = np.array([src.getBrightness().getFlux(tim.band) for src in cat]).astype(np.float32) F.flux_ivar = R.IV.astype(np.float32) F.fracflux = R.fitstats.profracflux.astype(np.float32) F.rchi2 = R.fitstats.prochi2 .astype(np.float32) program_name = sys.argv[0] version_hdr = get_version_header(program_name, decals.decals_dir) # HACK -- print only two directory names + filename of CPFILE. fname = os.path.basename(im.imgfn) d = os.path.dirname(im.imgfn) d1 = os.path.basename(d) d = os.path.dirname(d) d2 = os.path.basename(d) fname = os.path.join(d2, d1, fname) print('Trimmed filename to', fname) #version_hdr.add_record(dict(name='CPFILE', value=im.imgfn, comment='DECam comm.pipeline file')) version_hdr.add_record(dict(name='CPFILE', value=fname, comment='DECam comm.pipeline file')) version_hdr.add_record(dict(name='CPHDU', value=im.hdu, comment='DECam comm.pipeline ext')) version_hdr.add_record(dict(name='CAMERA', value='DECam', comment='Dark Energy Camera')) version_hdr.add_record(dict(name='EXPNUM', value=im.expnum, comment='DECam exposure num')) version_hdr.add_record(dict(name='CCDNAME', value=im.ccdname, comment='DECam CCD name')) version_hdr.add_record(dict(name='FILTER', value=tim.band, comment='Bandpass of this image')) version_hdr.add_record(dict(name='EXPOSURE', value='decam-%s-%s' % (im.expnum, im.ccdname), comment='Name of this image')) keys = ['TELESCOP','OBSERVAT','OBS-LAT','OBS-LONG','OBS-ELEV', 'INSTRUME'] for key in keys: if key in tim.primhdr: version_hdr.add_record(dict(name=key, value=tim.primhdr[key])) hdr = fitsio.FITSHDR() units = {'mjd':'sec', 'exptime':'sec', 'flux':'nanomaggy', 'flux_ivar':'1/nanomaggy^2'} columns = F.get_columns() for i,col in enumerate(columns): if col in units: hdr.add_record(dict(name='TUNIT%i' % (i+1), value=units[col])) outdir = os.path.dirname(opt.outfn) if len(outdir): trymakedirs(outdir) fitsio.write(opt.outfn, None, header=version_hdr, clobber=True) F.writeto(opt.outfn, header=hdr, append=True) print('Wrote', opt.outfn) print('Finished forced phot:', Time()-t0) return 0
def run_calibs(self, psfex=True, sky=True, funpack=False, git_version=None, force=False, **kwargs): from astrometry.util.file import trymakedirs from legacypipe.common import (create_temp, get_version_header, get_git_version) print('run_calibs for', self.name, ': sky=', sky, 'kwargs', kwargs) se = False if psfex and os.path.exists(self.psffn) and (not force): psfex = False if psfex: se = True if se and os.path.exists(self.sefn) and (not force): se = False if se: funpack = True if sky and (not force) and os.path.exists(self.splineskyfn): sky = False tmpimgfn = None tmpmaskfn = None # Unpacked image file funimgfn = self.imgfn funmaskfn = self.dqfn if funpack: # For FITS files that are not actually fpack'ed, funpack -E # fails. Check whether actually fpacked. hdr = fitsio.read_header(self.imgfn, ext=self.hdu) if not ((hdr['XTENSION'] == 'BINTABLE') and hdr.get('ZIMAGE', False)): print('Image', self.imgfn, 'HDU', self.hdu, 'is not actually fpacked; not funpacking, just imcopying.') fcopy = True tmpimgfn = create_temp(suffix='.fits') tmpmaskfn = create_temp(suffix='.fits') cmd = 'funpack -E %i -O %s %s' % (self.hdu, tmpimgfn, self.imgfn) print(cmd) if os.system(cmd): raise RuntimeError('Command failed: ' + cmd) funimgfn = tmpimgfn cmd = 'funpack -E %i -O %s %s' % (self.hdu, tmpmaskfn, self.dqfn) print(cmd) if os.system(cmd): print('Command failed: ' + cmd) M,hdr = self._read_fits(self.dqfn, ext=self.hdu, header=True) print('Read', M.dtype, M.shape) fitsio.write(tmpmaskfn, M, header=hdr, clobber=True) print('Wrote', tmpmaskfn, 'with fitsio') funmaskfn = tmpmaskfn if se: # grab header values... primhdr = self.read_image_primary_header() magzp = primhdr['MAGZERO'] seeing = self.pixscale * self.fwhm print('FWHM', self.fwhm, 'pix') print('pixscale', self.pixscale, 'arcsec/pix') print('Seeing', seeing, 'arcsec') if se: maskstr = '-FLAG_IMAGE ' + funmaskfn sedir = self.decals.get_se_dir() trymakedirs(self.sefn, dir=True) cmd = ' '.join([ 'sex', '-c', os.path.join(sedir, 'DECaLS.se'), maskstr, '-SEEING_FWHM %f' % seeing, '-PARAMETERS_NAME', os.path.join(sedir, 'DECaLS.param'), '-FILTER_NAME', os.path.join(sedir, 'gauss_5.0_9x9.conv'), '-STARNNW_NAME', os.path.join(sedir, 'default.nnw'), '-PIXEL_SCALE 0', # SE has a *bizarre* notion of "sigma" '-DETECT_THRESH 1.0', '-ANALYSIS_THRESH 1.0', '-MAG_ZEROPOINT %f' % magzp, '-CATALOG_NAME', self.sefn, funimgfn]) print(cmd) if os.system(cmd): raise RuntimeError('Command failed: ' + cmd) if psfex: sedir = self.decals.get_se_dir() trymakedirs(self.psffn, dir=True) # If we wrote *.psf instead of *.fits in a previous run... oldfn = self.psffn.replace('.fits', '.psf') if os.path.exists(oldfn): print('Moving', oldfn, 'to', self.psffn) os.rename(oldfn, self.psffn) else: primhdr = self.read_image_primary_header() plver = primhdr.get('PLVER', '') verstr = get_git_version() cmds = ['psfex -c %s -PSF_DIR %s %s' % (os.path.join(sedir, 'DECaLS.psfex'), os.path.dirname(self.psffn), self.sefn), 'modhead %s LEGPIPEV %s "legacypipe git version"' % (self.psffn, verstr), 'modhead %s PLVER %s "CP ver of image file"' % (self.psffn, plver)] for cmd in cmds: print(cmd) rtn = os.system(cmd) if rtn: raise RuntimeError('Command failed: ' + cmd + ': return value: %i' % rtn) if sky: #print('Fitting sky for', self) hdr = get_version_header(None, self.decals.get_decals_dir(), git_version=git_version) primhdr = self.read_image_primary_header() plver = primhdr.get('PLVER', '') hdr.delete('PROCTYPE') hdr.add_record(dict(name='PROCTYPE', value='ccd', comment='NOAO processing type')) hdr.add_record(dict(name='PRODTYPE', value='skymodel', comment='NOAO product type')) hdr.add_record(dict(name='PLVER', value=plver, comment='CP ver of image file')) slc = self.get_good_image_slice(None) #print('Good image slice is', slc) img = self.read_image(slice=slc) wt = self.read_invvar(slice=slc) from tractor.splinesky import SplineSky from scipy.ndimage.morphology import binary_dilation # Start by subtracting the overall median med = np.median(img[wt>0]) # Compute initial model... skyobj = SplineSky.BlantonMethod(img - med, wt>0, 512) skymod = np.zeros_like(img) skyobj.addTo(skymod) # Now mask bright objects in (image - initial sky model) sig1 = 1./np.sqrt(np.median(wt[wt>0])) masked = (img - med - skymod) > (5.*sig1) masked = binary_dilation(masked, iterations=3) masked[wt == 0] = True # Now find the final sky model using that more extensive mask skyobj = SplineSky.BlantonMethod(img - med, np.logical_not(masked), 512) # add the median back in skyobj.offset(med) if slc is not None: sy,sx = slc y0 = sy.start x0 = sx.start skyobj.shift(-x0, -y0) trymakedirs(self.splineskyfn, dir=True) skyobj.write_fits(self.splineskyfn, primhdr=hdr) print('Wrote sky model', self.splineskyfn) if tmpimgfn is not None: os.unlink(tmpimgfn) if tmpmaskfn is not None: os.unlink(tmpmaskfn)
def main(decals=None, opt=None): '''Driver function for forced photometry of individual DECam images. ''' if opt is None: parser = get_parser() opt = parser.parse_args() Time.add_measurement(MemMeas) t0 = Time() if os.path.exists(opt.outfn): print('Ouput file exists:', opt.outfn) sys.exit(0) if not opt.forced: opt.apphot = True zoomslice = None if opt.zoom is not None: (x0, x1, y0, y1) = opt.zoom zoomslice = (slice(y0, y1), slice(x0, x1)) ps = None if opt.plots is not None: from astrometry.util.plotutils import PlotSequence ps = PlotSequence(opt.plots) # Try parsing filename as exposure number. try: expnum = int(opt.filename) opt.filename = None except: # make this 'None' for decals.find_ccds() expnum = None # Try parsing HDU number try: opt.hdu = int(opt.hdu) ccdname = None except: ccdname = opt.hdu opt.hdu = -1 if decals is None: decals = Decals() if opt.filename is not None and opt.hdu >= 0: # Read metadata from file T = exposure_metadata([opt.filename], hdus=[opt.hdu]) print('Metadata:') T.about() else: # Read metadata from decals-ccds.fits table T = decals.find_ccds(expnum=expnum, ccdname=ccdname) print(len(T), 'with expnum', expnum, 'and CCDname', ccdname) if opt.hdu >= 0: T.cut(T.image_hdu == opt.hdu) print(len(T), 'with HDU', opt.hdu) if opt.filename is not None: T.cut( np.array([f.strip() == opt.filename for f in T.image_filename])) print(len(T), 'with filename', opt.filename) assert (len(T) == 1) im = decals.get_image_object(T[0]) tim = im.get_tractor_image(slc=zoomslice, pixPsf=True, splinesky=True) print('Got tim:', tim) if opt.catfn in ['DR1', 'DR2']: if opt.catalog_path is None: opt.catalog_path = opt.catfn.lower() margin = 20 TT = [] chipwcs = tim.subwcs bricks = bricks_touching_wcs(chipwcs, decals=decals) for b in bricks: # there is some overlap with this brick... read the catalog. fn = os.path.join(opt.catalog_path, 'tractor', b.brickname[:3], 'tractor-%s.fits' % b.brickname) if not os.path.exists(fn): print('WARNING: catalog', fn, 'does not exist. Skipping!') continue print('Reading', fn) T = fits_table(fn) ok, xx, yy = chipwcs.radec2pixelxy(T.ra, T.dec) W, H = chipwcs.get_width(), chipwcs.get_height() I = np.flatnonzero((xx >= -margin) * (xx <= (W + margin)) * (yy >= -margin) * (yy <= (H + margin))) T.cut(I) print('Cut to', len(T), 'sources within image + margin') # print('Brick_primary:', np.unique(T.brick_primary)) T.cut(T.brick_primary) print('Cut to', len(T), 'on brick_primary') T.cut((T.out_of_bounds == False) * (T.left_blob == False)) print('Cut to', len(T), 'on out_of_bounds and left_blob') TT.append(T) T = merge_tables(TT) T._header = TT[0]._header del TT # Fix up various failure modes: # FixedCompositeGalaxy(pos=RaDecPos[240.51147402832561, 10.385488075518923], brightness=NanoMaggies: g=(flux -2.87), r=(flux -5.26), z=(flux -7.65), fracDev=FracDev(0.60177207), shapeExp=re=3.78351e-44, e1=9.30367e-13, e2=1.24392e-16, shapeDev=re=inf, e1=-0, e2=-0) # -> convert to EXP I = np.flatnonzero( np.array([((t.type == 'COMP') and (not np.isfinite(t.shapedev_r))) for t in T])) if len(I): print('Converting', len(I), 'bogus COMP galaxies to EXP') for i in I: T.type[i] = 'EXP' # Same thing with the exp component. # -> convert to DEV I = np.flatnonzero( np.array([((t.type == 'COMP') and (not np.isfinite(t.shapeexp_r))) for t in T])) if len(I): print('Converting', len(I), 'bogus COMP galaxies to DEV') for i in I: T.type[i] = 'DEV' if opt.write_cat: T.writeto(opt.write_cat) print('Wrote catalog to', opt.write_cat) else: T = fits_table(opt.catfn) T.shapeexp = np.vstack((T.shapeexp_r, T.shapeexp_e1, T.shapeexp_e2)).T T.shapedev = np.vstack((T.shapedev_r, T.shapedev_e1, T.shapedev_e2)).T cat = read_fits_catalog(T, ellipseClass=tractor.ellipses.EllipseE) # print('Got cat:', cat) print('Forced photom...') opti = None if opt.ceres: from tractor.ceres_optimizer import CeresOptimizer B = 8 opti = CeresOptimizer(BW=B, BH=B) tr = Tractor([tim], cat, optimizer=opti) tr.freezeParam('images') for src in cat: src.freezeAllBut('brightness') src.getBrightness().freezeAllBut(tim.band) F = fits_table() F.brickid = T.brickid F.brickname = T.brickname F.objid = T.objid F.filter = np.array([tim.band] * len(T)) F.mjd = np.array([tim.primhdr['MJD-OBS']] * len(T)) F.exptime = np.array([tim.primhdr['EXPTIME']] * len(T)) ok, x, y = tim.sip_wcs.radec2pixelxy(T.ra, T.dec) F.x = (x - 1).astype(np.float32) F.y = (y - 1).astype(np.float32) if opt.apphot: import photutils img = tim.getImage() ie = tim.getInvError() with np.errstate(divide='ignore'): imsigma = 1. / ie imsigma[ie == 0] = 0. apimg = [] apimgerr = [] # Aperture photometry locations xxyy = np.vstack( [tim.wcs.positionToPixel(src.getPosition()) for src in cat]).T apxy = xxyy - 1. apertures = apertures_arcsec / tim.wcs.pixel_scale() print('Apertures:', apertures, 'pixels') for rad in apertures: aper = photutils.CircularAperture(apxy, rad) p = photutils.aperture_photometry(img, aper, error=imsigma) apimg.append(p.field('aperture_sum')) apimgerr.append(p.field('aperture_sum_err')) ap = np.vstack(apimg).T ap[np.logical_not(np.isfinite(ap))] = 0. F.apflux = ap ap = 1. / (np.vstack(apimgerr).T)**2 ap[np.logical_not(np.isfinite(ap))] = 0. F.apflux_ivar = ap if opt.forced: kwa = {} if opt.plots is None: kwa.update(wantims=False) R = tr.optimize_forced_photometry(variance=True, fitstats=True, shared_params=False, **kwa) if opt.plots: (data, mod, ie, chi, roi) = R.ims1[0] ima = tim.ima imchi = dict(interpolation='nearest', origin='lower', vmin=-5, vmax=5) plt.clf() plt.imshow(data, **ima) plt.title('Data: %s' % tim.name) ps.savefig() plt.clf() plt.imshow(mod, **ima) plt.title('Model: %s' % tim.name) ps.savefig() plt.clf() plt.imshow(chi, **imchi) plt.title('Chi: %s' % tim.name) ps.savefig() F.flux = np.array([ src.getBrightness().getFlux(tim.band) for src in cat ]).astype(np.float32) F.flux_ivar = R.IV.astype(np.float32) F.fracflux = R.fitstats.profracflux.astype(np.float32) F.rchi2 = R.fitstats.prochi2.astype(np.float32) program_name = sys.argv[0] version_hdr = get_version_header(program_name, decals.decals_dir) # HACK -- print only two directory names + filename of CPFILE. fname = os.path.basename(im.imgfn) d = os.path.dirname(im.imgfn) d1 = os.path.basename(d) d = os.path.dirname(d) d2 = os.path.basename(d) fname = os.path.join(d2, d1, fname) print('Trimmed filename to', fname) #version_hdr.add_record(dict(name='CPFILE', value=im.imgfn, comment='DECam comm.pipeline file')) version_hdr.add_record( dict(name='CPFILE', value=fname, comment='DECam comm.pipeline file')) version_hdr.add_record( dict(name='CPHDU', value=im.hdu, comment='DECam comm.pipeline ext')) version_hdr.add_record( dict(name='CAMERA', value='DECam', comment='Dark Energy Camera')) version_hdr.add_record( dict(name='EXPNUM', value=im.expnum, comment='DECam exposure num')) version_hdr.add_record( dict(name='CCDNAME', value=im.ccdname, comment='DECam CCD name')) version_hdr.add_record( dict(name='FILTER', value=tim.band, comment='Bandpass of this image')) version_hdr.add_record( dict(name='EXPOSURE', value='decam-%s-%s' % (im.expnum, im.ccdname), comment='Name of this image')) keys = [ 'TELESCOP', 'OBSERVAT', 'OBS-LAT', 'OBS-LONG', 'OBS-ELEV', 'INSTRUME' ] for key in keys: if key in tim.primhdr: version_hdr.add_record(dict(name=key, value=tim.primhdr[key])) hdr = fitsio.FITSHDR() units = { 'mjd': 'sec', 'exptime': 'sec', 'flux': 'nanomaggy', 'flux_ivar': '1/nanomaggy^2' } columns = F.get_columns() for i, col in enumerate(columns): if col in units: hdr.add_record(dict(name='TUNIT%i' % (i + 1), value=units[col])) outdir = os.path.dirname(opt.outfn) if len(outdir): trymakedirs(outdir) fitsio.write(opt.outfn, None, header=version_hdr, clobber=True) F.writeto(opt.outfn, header=hdr, append=True) print('Wrote', opt.outfn) print('Finished forced phot:', Time() - t0) return 0