def get_tractor_image_dr9(*args, **kwargs): sdss = kwargs.get('sdss', None) if sdss is None: from astrometry.sdss import DR9 curl = kwargs.pop('curl', False) kwargs['sdss'] = DR9(curl=curl) return get_tractor_image_dr8(*args, **kwargs)
def tractor_render_patch(run, camcol, field, roi, radec, celeste_src=None, bandname='r'): """ ROI = (x0, x1, y0, y1), zero indexed pixel coordinates """ # set up tractor if not os.path.exists('sdss_data'): os.makedirs('sdss_data') sdss = DR9(basedir='sdss_data') getim = st.get_tractor_image_dr9 getsrc = st.get_tractor_sources_dr9 #imkw = dict(zrange=[-3,100], sdss=sdss) # get images tim,tinf = getim(run, camcol, field, bandname, curl=True, roi=roi, sdss=sdss, psf='kl-pix') #, **imkw) tim.zr = tinf['zr'] # get corresponding sources #sources = getsrc(run, camcol, field, bandname, bands=[bandname], curl=True, roi=roi) sources = getsrc(run, camcol, field, radecrad=(radec[0], radec[1], .001)) if radec is not None and len(sources) > 1: locs = np.array([ [t.getPosition().ra, t.getPosition().dec] for t in sources]) dists = np.sum((locs - radec)**2, axis=1) ts = sources[dists.argmin()] else: ts = sources[0] print "tractor source: ", ts # set the first source to have the same parameters as dustin's if celeste_src is not None: print "setting source parameters" ts_pos = ts.getPosition() ts_pos.ra, ts_pos.dec = celeste_src.params.u from CelestePy.util.data import nanomaggies2mags band_mag = nanomaggies2mags(celeste_src.params.flux_dict[bandname]) ts_bright = ts.getBrightness() ts_bright.setMag(bandname, band_mag) import tractor.galaxy as tg if type(ts) == tg.ExpGalaxy or type(ts) == tg.DevGalaxy: print "setting exp or dev galaxy params (not composite)" ts.getShape().re = celeste_src.params.sigma ts.getShape().ab = celeste_src.params.rho ts.getShape().phi = celeste_src.params.phi elif type(ts) == tg.CompositeGalaxy: ts.shapeExp.re = celeste_src.params.sigma ts.shapeExp.ab = celeste_src.params.rho ts.shapeExp.phi = celeste_src.params.phi ts.shapeDev.re = celeste_src.params.sigma ts.shapeDev.ab = celeste_src.params.rho ts.shapeDev.phi = celeste_src.params.phi # create a tractor object, get a model image print "tractor source plotted:", ts tractor = Tractor(images = [tim], catalog=[ts]) mod = tractor.getModelImage(tim, srcs=[ts]) chi = tractor.getChiImage(imgi=0, srcs=[ts]) return mod, tim
def sdss_coadd(targetwcs, bands): from astrometry.sdss import DR9, band_index from astrometry.sdss import AsTransWrapper #sdss = DR9(basedir=photoobjdir) #sdss.useLocalTree() sdss = DR9(basedir='tmp') sdss.saveUnzippedFiles('tmp') #wfn = sdss.filenames.get('window_flist', None) wfn = os.path.join(os.environ.get('PHOTO_RESOLVE', ''), 'window_flist.fits') from astrometry.sdss.fields import radec_to_sdss_rcf ra, dec = targetwcs.radec_center() rad = targetwcs.radius() rad = rad + np.hypot(10., 14.) / 2. / 60. print('Searching for run,camcol,fields with radius', rad, 'deg') RCF = radec_to_sdss_rcf(ra, dec, radius=rad * 60., tablefn=wfn) print('Found %i fields possibly in range' % len(RCF)) H, W = targetwcs.shape sdsscoimgs = [np.zeros((H, W), np.float32) for band in bands] sdsscons = [np.zeros((H, W), np.float32) for band in bands] for run, camcol, field, r, d in RCF: for iband, band in enumerate(bands): bandnum = band_index(band) sdss.retrieve('frame', run, camcol, field, band) frame = sdss.readFrame(run, camcol, field, bandnum) print('Got frame', frame) h, w = frame.getImageShape() simg = frame.getImage() wcs = AsTransWrapper(frame.astrans, w, h, 0.5, 0.5) try: Yo, Xo, Yi, Xi, nil = resample_with_wcs(targetwcs, wcs) except OverlapError: continue sdsscoimgs[iband][Yo, Xo] += simg[Yi, Xi] sdsscons[iband][Yo, Xo] += 1 for co, n in zip(sdsscoimgs, sdsscons): co /= np.maximum(1e-6, n) return sdsscoimgs, sdsscons
def read_photoobjs_in_wcs(wcs, margin, cols=None, cutToPrimary=True, wfn=None, sdss=None): ''' Read photoObjs that are inside the given 'wcs', plus 'margin' in degrees. ''' import logging log = logging.getLogger('read_photoobjs_in_wcs') ra, dec = wcs.radec_center() rad = wcs.radius() rad += np.hypot(14., 10.) / 2 / 60. # a little extra margin rad += margin if sdss is None: from astrometry.sdss import DR9 sdss = DR9() if wfn is None: wfn = sdss.filenames.get('window_flist', None) if wfn is None: wfn = 'window_flist.fits' if not os.path.exists(wfn): print('File does not exist:', wfn, '; downloading...') wfn = sdss.retrieve('window_flist', None, None, None, rerun='xxx') print('Retrieved', wfn) else: print('Using', wfn) print('Searching for run,camcol,fields with radius', rad, 'deg') RCF = radec_to_sdss_rcf(ra, dec, radius=rad * 60., tablefn=wfn) log.debug('Found %i fields possibly in range' % len(RCF)) pixmargin = margin * 3600. / wcs.pixel_scale() W, H = wcs.get_width(), wcs.get_height() TT = [] for run, camcol, field, r, d in RCF: log.debug('RCF %i/%i/%i' % (run, camcol, field)) rr = sdss.get_rerun(run, field=field) if rr in [None, '157']: log.debug('Rerun 157') continue fn = sdss.retrieve('photoObj', run, camcol, field, rerun=rr) #fn = get_photoobj_filename(rr, run, camcol, field) T = fits_table(fn, columns=cols) if T is None: log.debug('read 0 from %s' % fn) continue log.debug('read %i from %s' % (len(T), fn)) # while we're reading it, record its length for later... #get_photoobj_length(rr, run, camcol, field) ok, x, y = wcs.radec2pixelxy(T.ra, T.dec) x -= 1 y -= 1 T.cut((x > -pixmargin) * (x < (W + pixmargin)) * (y > -pixmargin) * (y < (H + pixmargin))) if cutToPrimary: T.cut((T.resolve_status & 256) > 0) log.debug('cut to %i within target area and PRIMARY.' % len(T)) else: log.debug('cut to %i within target area.' % len(T)) if len(T) == 0: continue TT.append(T) if not len(TT): return None T = merge_tables(TT) return T
def get_sdss_sources(bands, targetwcs, photoobjdir=None, local=True, extracols=[], ellipse=None): ''' Finds SDSS catalog sources within the given `targetwcs` region, returning FITS table and Tractor Source objects. Returns ------- cat : Tractor Catalog object Tractor Source objects for the SDSS catalog entries objs : fits_table object FITS table object for the sources. Row-by-row parallel to `cat`. ''' from astrometry.sdss import DR9, band_index, AsTransWrapper from astrometry.sdss.fields import read_photoobjs_in_wcs from tractor.sdss import get_tractor_sources_dr9 # FIXME? margin = 0. if ellipse is None: from tractor.ellipses import EllipseESoft ellipse = EllipseESoft.fromRAbPhi sdss = DR9(basedir=photoobjdir) if local: local = (local and ('BOSS_PHOTOOBJ' in os.environ) and ('PHOTO_RESOLVE' in os.environ)) if local: sdss.useLocalTree() cols = [ 'objid', 'ra', 'dec', 'fracdev', 'objc_type', 'theta_dev', 'theta_deverr', 'ab_dev', 'ab_deverr', 'phi_dev_deg', 'theta_exp', 'theta_experr', 'ab_exp', 'ab_experr', 'phi_exp_deg', 'resolve_status', 'nchild', 'flags', 'objc_flags', 'run', 'camcol', 'field', 'id', 'psfflux', 'psfflux_ivar', 'cmodelflux', 'cmodelflux_ivar', 'modelflux', 'modelflux_ivar', 'devflux', 'expflux', 'extinction' ] + extracols # If we have a window_flist file cut to primary objects, use that. # This file comes from svn+ssh://astrometry.net/svn/trunk/projects/wise-sdss-phot # cut-window-flist.py, and used resolve/2013-07-29 (pre-DR13) as input. wfn = 'window_flist-cut.fits' if not os.path.exists(wfn): # default to the usual window_flist.fits file. wfn = None objs = read_photoobjs_in_wcs(targetwcs, margin, sdss=sdss, cols=cols, wfn=wfn) if objs is None: print('No photoObjs in wcs') return None, None print('Got', len(objs), 'photoObjs') print('Bands', bands, '->', list(bands)) # It can be string-valued objs.objid = np.array([int(x) if len(x) else 0 for x in objs.objid]) srcs = get_tractor_sources_dr9(None, None, None, objs=objs, sdss=sdss, bands=list(bands), nanomaggies=True, fixedComposites=True, useObjcType=True, ellipse=ellipse) print('Created', len(srcs), 'Tractor sources') # record coordinates in target brick image ok, objs.tx, objs.ty = targetwcs.radec2pixelxy(objs.ra, objs.dec) objs.tx -= 1 objs.ty -= 1 W, H = targetwcs.get_width(), targetwcs.get_height() objs.itx = np.clip(np.round(objs.tx), 0, W - 1).astype(int) objs.ity = np.clip(np.round(objs.ty), 0, H - 1).astype(int) cat = Catalog(*srcs) return cat, objs
# plot celeste rendering # ########################### simg, ylim, xlim = s.compute_scatter_on_pixels(fimg) print "\n========== celeste render ===============\n" s.plot(fimg, ax=axarr[0], unit_flux=True) axarr[0].set_title("Celeste Render") ########################## # plot tractor rendering # ######################### print "\n========== tractor render ===============\n" from tractor import sdss as st from tractor import Tractor from astrometry.sdss import DR9 # get images sdss = DR9(basedir='sdss_data') tim, tinf = st.get_tractor_image_dr9(run, camcol, field, fimg.band, curl=True, roi=(xlim[0], xlim[1] - 1, ylim[0], ylim[1] - 1), sdss=sdss, psf='kl-gm') #patch = ts.getModelPatch(tim) px, py = fimg.equa2pixel(s.params.u) - np.array([xlim[0], ylim[0]]) patch = ts.getUnitFluxModelPatch(tim) #, px, py) mod = patch.getImage() # get corresponding sources
def refit_galaxies(T, band='i', S=100, intermediate_fn='refit-%06i.fits', mp=None, modswitch=False, errors=False): if mp is None: mp = multiproc() sdss = DR9(basedir='paper0-data-dr9') print 'basedir', sdss.basedir print 'dasurl', sdss.dasurl N = len(T) ps = [ ('my_', ''), ('init_', ''), ] if modswitch: ps.append(('sw_', '')) if errors: ps.append(('my_', '_err')) for prefix, suffix in ps: for c in [ 'exprad_', 'expab_', 'expphi_', 'expmag_', 'devrad_', 'devab_', 'devphi_', 'devmag_' ]: T.set(prefix + c + band + suffix, np.zeros(N, dtype=np.float32)) for c in ['ra', 'dec']: if len(suffix): dt = np.float32 else: dt = np.float64 T.set(prefix + c + suffix, np.zeros(N, dtype=dt)) # assume suffix implies _error; omit prefix_type_err field if len(suffix): continue T.set(prefix + 'type', np.chararray(len(T), 1)) if modswitch: T.set('sw_dlnp', np.zeros(len(T), np.float32)) args = [] for gali in range(len(T)): ti = T[gali] args.append((ti, band, S, sdss, gali, modswitch, errors)) # Run in blocks. tinew = [] B = 0 while len(args): N = 100 #N = 4 B += N # Pop N args off the front of the list thisargs = args[:N] args = args[N:] # Run on those args thisres = mp.map(_refit_gal, thisargs) #tinew.extend(thisres) #print 'tinew:', tinew for resi, argi in zip(thisres, thisargs): ### gali = argi[4] ### if resi is None: print 'Result', gali, 'is None' continue print 'Saving result', gali T[gali] = resi #for gali in range(min(len(T), len(tinew))): # tin = tinew[gali] # if tin is None: # print 'Skipping', gali # continue # T[gali] = tin #Ti.about() if intermediate_fn: T.writeto(intermediate_fn % B)
def main(): from optparse import OptionParser import sys # Otherwise plotting code can raise floating-point errors np.seterr(under='print') tune = [] def store_value (option, opt, value, parser): if opt == '--ntune': tune.append(('n',value)) elif opt == '--itune': tune.append(('i',value)) parser = OptionParser(usage=('%prog [options] [-r <run> -c <camcol> -f <field> -b <band>]')) parser.add_option('-r', '--run', dest='run', type='int') parser.add_option('-c', '--camcol', dest='camcol', type='int') parser.add_option('-f', '--field', dest='field', type='int') parser.add_option('-b', '--band', dest='band', help='SDSS Band (u, g, r, i, z)') parser.add_option('--dg', action='store_true', default=False, help='Use double-Gaussian PSF model (default is Gaussian mixture approximation of pixelized model') parser.add_option('-R', '--radec', dest='radec', nargs=2, type=str, help='RA,Dec center: float degrees or hh:mm:ss +-dd:mm:ss') parser.add_option('-s', '--size', dest='pixsize', type=int, help='Pixel size when using RA,Dec center option') parser.add_option('--drfields', dest='drfields', help='FITS table of SDSS fields: default dr%ifields.fits, etc') parser.add_option('--curl', dest='curl', action='store_true', default=False, help='Use "curl", not "wget", to download files') parser.add_option('--ntune', action='callback', callback=store_value, type=int, help='Improve synthetic image by locally optimizing likelihood for nsteps iterations') parser.add_option('--itune', action='callback', callback=store_value, type=int, nargs=2, help='Optimizes each source individually') parser.add_option('--roi', dest='roi', type=int, nargs=4, help='Select an x0,x1,y0,y1 subset of the image') parser.add_option('--prefix', dest='prefix', help='Set output filename prefix; default is the SDSS RRRRRR-BC-FFFF string (run, band, camcol, field)') parser.add_option('--sdss-dir', help='Set base directory for SDSS data') parser.add_option('--const-invvar', help='Constant invvar, not per-pixel variable', action='store_true', default=False) parser.add_option('-v', '--verbose', dest='verbose', action='count', default=0, help='Make more verbose') parser.add_option('-d','--debug',dest='debug',action='store_true',default=False,help="Trigger debug images") parser.add_option('--plotAll',dest='plotAll',action='store_true',default=False,help="Makes a plot for each source") parser.add_option('--no-arcsinh', dest='noarcsinh', action='store_true', help='Do not arcsinh-stretch plots') parser.add_option('--lbfgsb', dest='lbfgsb', action='store_true', default=False, help='Use L-BFGS-B optimization method') parser.add_option('--scale', dest='scale', type=int, help='Scale images down by this factor') parser.add_option('--unzip', dest='unzip', help='Save unzipped frame files in this directory') parser.add_option('--no-flipbook', dest='flipbook', default=True, action='store_false', help='Do not write PDF flip-book of plots') opt,args = parser.parse_args() if opt.verbose == 0: lvl = logging.INFO else: lvl = logging.DEBUG logging.basicConfig(level=lvl, format='%(message)s', stream=sys.stdout) run = opt.run field = opt.field camcol = opt.camcol bands = [] if run is None and field is None and camcol is None and opt.band is None: # Demo mode... ## FIXME -- find a nice field here run = 1752 camcol = 3 field = 164 opt.band = 'r' opt.curl = True tune.extend([('i',[1,1]), ('n',1)]) if opt.roi is None: opt.roi = [100,600,100,600] print() print('Demo mode: grabbing Run/Camcol/Field/Band %i/%i/%i/%s' % (run, camcol, field, opt.band)) print('Using SDSS DR9 data') print() if opt.band is None: parser.print_help() print() print('Must supply band (-b [u | g |r |i | z])') print() sys.exit(-1) for char in opt.band: bands.append(char) if not char in ['u','g','r','i','z']: parser.print_help() print() print('Must supply band (u/g/r/i/z)') print() sys.exit(-1) rerun = 0 usercf = (run is not None and field is not None and camcol is not None) userd = (opt.radec is not None and opt.pixsize is not None) if not (usercf or userd) or len(bands)==0: parser.print_help() print('Must supply (--run, --camcol, --field) or (--radec, --size), and --band') sys.exit(-1) bandname = bands[0] #initial position and shape prefix = opt.prefix if userd: ra = opt.radec[0] dec = opt.radec[1] size = opt.pixsize if prefix is None: if usercf: prefix = '%06i-%i-%04i' % (run,camcol, field) else: prefix = '%s-%s' % (ra, dec) if userd: # convert h:m:s to deg try: ra = float(ra) except: ra = ra.replace(':',' ') ra = hmsstring2ra(ra) try: dec = float(dec) except: dec = dec.replace(':',' ') dec = dmsstring2dec(dec) if opt.sdss_dir is not None: sdss = DR9(basedir=opt.sdss_dir) else: sdss = DR9() getim = st.get_tractor_image_dr9 getsrc = st.get_tractor_sources_dr9 imkw = dict(zrange=[-3,100], sdss=sdss) if opt.const_invvar: imkw.update(invvarAtCenter=True) if opt.unzip: sdss.saveUnzippedFiles(opt.unzip) tims = [] for bandname in bands: if userd: if not usercf: tfn = opt.drfields if tfn is None: tfn = 'dr%ifields.fits' % drnum rcfs = radec_to_sdss_rcf(ra, dec, radius=math.hypot(radius,13./2.), tablefn=tfn) if len(rcfs) == 0: print('RA,Dec (%.3f,%.3f): found no overlapping SDSS fields in file %s' % (ra, dec, tfn)) sys.exit(-1) if len(rcfs) > 1: print('Found %i Run,Camcol,Fields overlapping RA,Dec (%.3f,%.3f): taking the first one' % (len(rcfs), ra, dec)) rcfs = rcfs[0] run,camcol,field = rcfs[:3] imkw.update(roiradecsize = (ra, dec, opt.pixsize)) if opt.dg: imkw.update(psf='dg') tim,tinf = getim(run, camcol, field, bandname, curl=opt.curl, roi=opt.roi, **imkw) tim.zr = tinf['zr'] if userd: opt.roi = tinf['roi'] tims.append(tim) if opt.scale: print('Scaling images by', opt.scale) tims = [st.scale_sdss_image(tim, opt.scale) for tim in tims] sources = getsrc(run, camcol, field, bandname, bands=bands, curl=opt.curl, roi=opt.roi, sdss=sdss, retrieve=False) tractor = Tractor(tims, sources) sa = dict(debug=opt.debug, plotAll=opt.plotAll, roi=opt.roi) if opt.noarcsinh: sa.update(nlscale=0) for j,band in enumerate(bands): save('initial-%s-' % (band) + prefix, tractor, imgi=j, **sa) lnp0 = tractor.getLogProb() print('Initial lnprob:', lnp0) for im in tractor.images: im.freezeAllParams() im.thawParam('sky') for count, each in enumerate(tune): if each[0]=='n': tractor.catalog.thawAllParams() tractor.images.thawParamsRecursive('sky') for i in range(each[1]): if opt.lbfgsb: tractor.optimize_lbfgsb() else: tractor.optimize() for j,band in enumerate(bands): save('tune-%d-%d-%s-' % (count+1, i+1,band) + prefix, tractor, imgi=j, **sa) lnp1 = tractor.getLogProb() print('After optimization: lnprob', lnp1) print(' delta-lnprob:', lnp1 - lnp0) elif each[0]=='i': tractor.images.freezeParamsRecursive('sky') for i in range(each[1][0]): for j,src in enumerate(tractor.getCatalog()): tractor.catalog.freezeAllBut(src) if i < 6: print('Freezing position') src.freezeParam('pos') print('Optimizing:') for nm in tractor.getParamNames(): print(nm) for step in range(each[1][1]): if opt.lbfgsb: tractor.optimize_lbfgsb(plotfn='synt-opt-i%i-s%04i.png' % (i,j)) else: tractor.optimize() src.unfreezeParam('pos') for j,band in enumerate(bands): save('tune-%d-%d-%s-' % (count+1,i+1,band) + prefix, tractor, imgi=j, **sa) lnp1 = tractor.getLogProb() print('After optimization: lnprob', lnp1) print(' delta-lnprob:', lnp1 - lnp0) if opt.flipbook: makeflipbook(opt, prefix,tune,len(tractor.getCatalog()),bands) print() print('Created flip-book flip-%s.pdf' % prefix) print('Done')
def get_tractor_sources_cas_dr9(table, bandname='r', bands=None, extrabands=None, nanomaggies=False): ''' table: filename or astrometry.util.fits.fits_table() object ''' from astrometry.sdss import band_names from astrometry.util.fits import fits_table if isinstance(table, basestring): cas = fits_table(table) else: cas = table # Make it look like a "photoObj" file. cols = cas.get_columns() N = len(cas) T = tabledata() T.ra = cas.ra T.dec = cas.dec # nchild if not 'nchild' in cols: T.nchild = np.zeros(N, int) else: T.nchild = cas.nchild # rowc,colc -- shouldn't be necessary... if not 'objc_flags' in cols: T.objc_flags = np.zeros(N, int) else: T.objc_flags = cas.objc_flags allbands = band_names() nbands = len(allbands) colmap = [ ('phi_dev_deg', 'devphi'), ('phi_exp_deg', 'expphi'), ('theta_dev', 'devrad'), ('theta_exp', 'exprad'), ('ab_dev', 'devab'), ('ab_exp', 'expab'), ('psfflux', 'psfflux'), ('cmodelflux', 'cmodelflux'), ('devflux', 'devflux'), ('expflux', 'expflux'), ('fracdev', 'fracdev'), ('prob_psf', 'probpsf'), ] for c1, c2 in colmap: T.set(c1, np.zeros((N, nbands))) for bi, b in enumerate(allbands): for c1, c2 in colmap: cname = '%s_%s' % (c2, b) if cname in cols: T.get(c1)[:, bi] = cas.get(cname) return _get_sources(-1, -1, -1, release='DR9', objs=T, sdss=DR9(), bandname=bandname, bands=bands, nanomaggies=nanomaggies, extrabands=extrabands)
def map_sdss(req, ver, zoom, x, y, savecache=None, tag='sdss', get_images=False, ignoreCached=False, wcs=None, forcecache=False, forcescale=None, bestOnly=False, bands='gri', **kwargs): from decals import settings if savecache is None: savecache = settings.SAVE_CACHE zoom = int(zoom) zoomscale = 2.**zoom x = int(x) y = int(y) if zoom < 0 or x < 0 or y < 0 or x >= zoomscale or y >= zoomscale: raise RuntimeError('Invalid zoom,x,y %i,%i,%i' % (zoom, x, y)) ver = int(ver) if not ver in tileversions[tag]: raise RuntimeError('Invalid version %i for tag %s' % (ver, tag)) basedir = settings.DATA_DIR tilefn = os.path.join(basedir, 'tiles', tag, '%i/%i/%i/%i.jpg' % (ver, zoom, x, y)) if os.path.exists(tilefn) and not ignoreCached: if get_images: return None return send_file(tilefn, 'image/jpeg', expires=oneyear, modsince=req.META.get('HTTP_IF_MODIFIED_SINCE')) if not savecache: import tempfile f, tilefn = tempfile.mkstemp(suffix='.jpg') os.close(f) if wcs is None: try: wcs, W, H, zoomscale, zoom, x, y = get_tile_wcs(zoom, x, y) except RuntimeError as e: if get_images: return None return HttpResponse(e.strerror) else: W = wcs.get_width() H = wcs.get_height() from astrometry.util.fits import fits_table import numpy as np from astrometry.libkd.spherematch import tree_build_radec, tree_search_radec from astrometry.util.starutil_numpy import degrees_between, arcsec_between from astrometry.util.resample import resample_with_wcs, OverlapError from astrometry.util.util import Tan, Sip import fitsio print('Tile wcs: center', wcs.radec_center(), 'pixel scale', wcs.pixel_scale()) global w_flist global w_flist_tree if w_flist is None: w_flist = fits_table( os.path.join(settings.DATA_DIR, 'sdss', 'window_flist.fits'), columns=['run', 'rerun', 'camcol', 'field', 'ra', 'dec', 'score']) print('Read', len(w_flist), 'window_flist entries') w_flist.cut(w_flist.rerun == '301') print('Cut to', len(w_flist), 'in rerun 301') w_flist_tree = tree_build_radec(w_flist.ra, w_flist.dec) # SDSS field size radius = 1.01 * np.hypot(10., 14.) / 2. / 60. # leaflet tile size ra, dec = wcs.pixelxy2radec(W / 2., H / 2.)[-2:] r0, d0 = wcs.pixelxy2radec(1, 1)[-2:] r1, d1 = wcs.pixelxy2radec(W, H)[-2:] radius = radius + max(degrees_between(ra, dec, r0, d0), degrees_between(ra, dec, r1, d1)) J = tree_search_radec(w_flist_tree, ra, dec, radius) print(len(J), 'overlapping SDSS fields found') if len(J) == 0: if get_images: return None if forcecache: # create symlink to blank.jpg! trymakedirs(tilefn) src = os.path.join(settings.STATIC_ROOT, 'blank.jpg') if os.path.exists(tilefn): os.unlink(tilefn) os.symlink(src, tilefn) print('Symlinked', tilefn, '->', src) from django.http import HttpResponseRedirect return HttpResponseRedirect(settings.STATIC_URL + 'blank.jpg') ww = [1, W * 0.25, W * 0.5, W * 0.75, W] hh = [1, H * 0.25, H * 0.5, H * 0.75, H] r, d = wcs.pixelxy2radec( [1] * len(hh) + ww + [W] * len(hh) + list(reversed(ww)), hh + [1] * len(ww) + list(reversed(hh)) + [H] * len(ww))[-2:] scaled = 0 scalepat = None scaledir = 'sdss' if zoom <= 13 and forcescale is None: # Get *actual* pixel scales at the top & bottom r1, d1 = wcs.pixelxy2radec(W / 2., H)[-2:] r2, d2 = wcs.pixelxy2radec(W / 2., H - 1.)[-2:] r3, d3 = wcs.pixelxy2radec(W / 2., 1.)[-2:] r4, d4 = wcs.pixelxy2radec(W / 2., 2.)[-2:] # Take the min = most zoomed-in scale = min(arcsec_between(r1, d1, r2, d2), arcsec_between(r3, d3, r4, d4)) native_scale = 0.396 scaled = int(np.floor(np.log2(scale / native_scale))) print('Zoom:', zoom, 'x,y', x, y, 'Tile pixel scale:', scale, 'Scale step:', scaled) scaled = np.clip(scaled, 1, 7) dirnm = os.path.join(basedir, 'scaled', scaledir) scalepat = os.path.join( dirnm, '%(scale)i%(band)s', '%(rerun)s', '%(run)i', '%(camcol)i', 'sdss-%(run)i-%(camcol)i-%(field)i-%(band)s.fits') if forcescale is not None: scaled = forcescale rimgs = [np.zeros((H, W), np.float32) for band in bands] rns = [np.zeros((H, W), np.float32) for band in bands] from astrometry.sdss import AsTransWrapper, DR9 sdss = DR9(basedir=settings.SDSS_DIR) sdss.saveUnzippedFiles(settings.SDSS_DIR) #sdss.setFitsioReadBZ2() if settings.SDSS_PHOTOOBJS: sdss.useLocalTree(photoObjs=settings.SDSS_PHOTOOBJS, resolve=settings.SDSS_RESOLVE) for jnum, j in enumerate(J): print('SDSS field', jnum, 'of', len(J), 'for zoom', zoom, 'x', x, 'y', y) im = w_flist[j] if im.score >= 0.5: weight = 1. else: weight = 0.001 for band, rimg, rn in zip(bands, rimgs, rns): if im.rerun != '301': continue tmpsuff = '.tmp%08i' % np.random.randint(100000000) basefn = sdss.retrieve('frame', im.run, im.camcol, field=im.field, band=band, rerun=im.rerun, tempsuffix=tmpsuff) if scaled > 0: fnargs = dict(band=band, rerun=im.rerun, run=im.run, camcol=im.camcol, field=im.field) fn = get_scaled(scalepat, fnargs, scaled, basefn, read_base_wcs=read_astrans, read_wcs=read_sip_wcs) print('get_scaled:', fn) else: fn = basefn frame = None if fn == basefn: frame = sdss.readFrame(im.run, im.camcol, im.field, band, filename=fn) h, w = frame.getImageShape() # Trim off the overlapping top of the image # Wimp out and instead of trimming 128 pix, trim 124! trim = 124 subh = h - trim astrans = frame.getAsTrans() fwcs = AsTransWrapper(astrans, w, subh) fullimg = frame.getImage() fullimg = fullimg[:-trim, :] else: fwcs = Sip(fn) fitsimg = fitsio.FITS(fn)[0] h, w = fitsimg.get_info()['dims'] fullimg = fitsimg.read() try: #Yo,Xo,Yi,Xi,nil = resample_with_wcs(wcs, fwcs, [], 3) Yo, Xo, Yi, Xi, [resamp ] = resample_with_wcs(wcs, fwcs, [fullimg], 2) except OverlapError: continue if len(Xi) == 0: #print 'No overlap' continue if sdssps is not None: x0 = Xi.min() x1 = Xi.max() y0 = Yi.min() y1 = Yi.max() slc = (slice(y0, y1 + 1), slice(x0, x1 + 1)) if frame is not None: img = frame.getImageSlice(slc) else: img = fitsimg[slc] #rimg[Yo,Xo] += img[Yi-y0, Xi-x0] if bestOnly: K = np.flatnonzero(weight > rn[Yo, Xo]) print('Updating', len(K), 'of', len(Yo), 'pixels') if len(K): rimg[Yo[K], Xo[K]] = resamp[K] * weight rn[Yo[K], Xo[K]] = weight else: rimg[Yo, Xo] += resamp * weight rn[Yo, Xo] += weight if sdssps is not None: # goodpix = np.ones(img.shape, bool) # fpM = sdss.readFpM(im.run, im.camcol, im.field, band) # for plane in [ 'INTERP', 'SATUR', 'CR', 'GHOST' ]: # fpM.setMaskedPixels(plane, goodpix, False, roi=[x0,x1,y0,y1]) plt.clf() #ima = dict(vmin=-0.05, vmax=0.5) #ima = dict(vmin=-0.5, vmax=2.) ima = dict(vmax=np.percentile(img, 99)) plt.subplot(2, 3, 1) dimshow(img, ticks=False, **ima) plt.title('image') rthis = np.zeros_like(rimg) #rthis[Yo,Xo] += img[Yi-y0, Xi-x0] rthis[Yo, Xo] += resamp plt.subplot(2, 3, 2) dimshow(rthis, ticks=False, **ima) plt.title('resampled') # plt.subplot(2,3,3) # dimshow(goodpix, ticks=False, vmin=0, vmax=1) # plt.title('good pix') plt.subplot(2, 3, 4) dimshow(rimg / np.maximum(rn, 1), ticks=False, **ima) plt.title('coadd') plt.subplot(2, 3, 5) dimshow(rn, vmin=0, ticks=False) plt.title('coverage: max %i' % rn.max()) plt.subplot(2, 3, 6) rgb = sdss_rgb( [rimg / np.maximum(rn, 1) for rimg, rn in zip(rimgs, rns)], bands) dimshow(rgb) plt.suptitle('SDSS %s, R/C/F %i/%i/%i' % (band, im.run, im.camcol, im.field)) sdssps.savefig() for rimg, rn in zip(rimgs, rns): rimg /= np.maximum(rn, 1e-3) del rns if get_images: return rimgs rgb = sdss_rgb(rimgs, bands) trymakedirs(tilefn) save_jpeg(tilefn, rgb) print('Wrote', tilefn) return send_file(tilefn, 'image/jpeg', unlink=(not savecache))