Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
    # 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
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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')
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
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))