Exemple #1
0
    w1 /= 2
    w2 /= 2

fns = ['w1-lbzoom-5-1800-u-wcs.fits',
       'w2-lbzoom-5-1800-u-wcs.fits',]
u1,u2 = [fitsio.read(fn) for fn in fns]

plt.clf()
plt.loglog(np.maximum(1000, w1.ravel()), np.maximum(1000, u1.ravel()), 'k.', alpha=0.01)
plt.savefig('w1.png')
plt.clf()
plt.loglog(np.maximum(1000, w2.ravel()), np.maximum(1000, u2.ravel()), 'k.', alpha=0.01)
plt.savefig('w2.png')


S,Q = 3000,25
rgb = _unwise_to_rgb([w1, w2], S=[S,S], Q=Q)
plt.imsave(jpegfn, rgb, origin='lower')


#w1 -= np.median(w1[600:1200, 1200:2400])
#w2 -= np.median(w2[600:1200, 1200:2400])

w1 -= np.percentile(w1[600:1200, 1200:2400], 25)
w2 -= np.percentile(w2[600:1200, 1200:2400], 25)


S,Q = 3000,25
rgb = _unwise_to_rgb([w1, w2], S=[S,S], Q=Q)
plt.imsave(jpegfn.replace('.png','-2.png'), rgb, origin='lower')
#fns = ['unwise2-w1-lbzoom-5-1800.fits',
#       'unwise2-w2-lbzoom-5-1800.fits',]

imgs = [fitsio.read(fn) for fn in fns]
wcs = anwcs(fns[0])
print('WCS header', wcs)

# HACK -- colormap scalings
for img in imgs:
    img /= 10.

#from decals import settings
from map.views import _unwise_to_rgb

S,Q = 3000,25
rgb = _unwise_to_rgb(imgs, S=[S]*len(imgs), Q=Q)

H,W = imgs[0].shape
print('Image size', W, 'x', H)
ok,l1,b1 = wcs.pixelxy2radec(1, (H+1)/2.)
ok,l2,b2 = wcs.pixelxy2radec(W, (H+1)/2.)
ok,l3,b3 = wcs.pixelxy2radec((W+1)/2., 1)
ok,l4,b4 = wcs.pixelxy2radec((W+1)/2., H)

print('L,B', (l1,b1), (l2,b2), (l3,b3), (l4,b4))

llo,lhi = l2,l1+360
blo,bhi = b3,b4

ps = PlotSequence('xbulge', suffix='pdf')
Exemple #3
0
def top_levels(mp, opt):
    from map.views import save_jpeg, trymakedirs

    if opt.kind in [
            'decaps2', 'decaps2-model', 'decaps2-resid', 'mzls+bass-dr4',
            'mzls+bass-dr4-model', 'mzls+bass-dr4-resid', 'decals-dr5',
            'decals-dr5-model', 'decals-dr5-resid', 'mzls+bass-dr6',
            'mzls+bass-dr6-model', 'mzls+bass-dr6-resid', 'eboss',
            'unwise-neo2', 'sdss2'
    ]:
        import pylab as plt
        from decals import settings
        from legacypipe.survey import get_rgb
        import fitsio
        from scipy.ndimage.filters import gaussian_filter
        from map.views import trymakedirs
        from map.views import _unwise_to_rgb
        tag = opt.kind

        rgbkwargs = {}
        if opt.kind == 'unwise-neo2':
            bands = [1, 2]
            get_rgb = _unwise_to_rgb
        elif opt.kind == 'sdss2':
            bands = 'gri'
            get_rgb = sdss_rgb
        else:
            bands = 'grz'
            get_rgb = dr2_rgb

        ver = tileversions.get(opt.kind, [1])[-1]
        print('Version', ver)
        basescale = 5

        pat = os.path.join(settings.DATA_DIR, 'tiles', tag, '%(ver)s',
                           '%(zoom)i', '%(x)i', '%(y)i.jpg')
        patdata = dict(ver=ver)

        tilesize = 256
        tiles = 2**basescale
        side = tiles * tilesize

        basepat = 'base-%s-%i-%%s.fits' % (opt.kind, basescale)

        basefns = [basepat % band for band in bands]
        if not all([os.path.exists(fn) for fn in basefns]):
            bases = [np.zeros((side, side), np.float32) for band in bands]

            args = []
            xy = []
            if opt.y1 is None:
                opt.y1 = tiles
            if opt.x0 is None:
                opt.x0 = 0
            if opt.x1 is None:
                opt.x1 = tiles
            for y in range(opt.y0, opt.y1):
                for x in range(opt.x0, opt.x1):
                    args.append((opt.kind, basescale, x, y, False, True))
                    xy.append((x, y))

            tiles = mp.map(_one_tile, args)

            for ims, (x, y) in zip(tiles, xy):

                #for a,(x,y) in zip(args, xy):
                #print('_one_tile args:', a)
                #ims = _one_tile(a)
                #print('-> ', ims)

                if ims is None:
                    continue
                for im, base in zip(ims, bases):
                    if im is None:
                        continue
                    base[y * tilesize:(y + 1) * tilesize,
                         x * tilesize:(x + 1) * tilesize] = im

            for fn, base in zip(basefns, bases):
                fitsio.write(fn, base, clobber=True)
        else:
            print('Reading', basefns)
            bases = [fitsio.read(fn) for fn in basefns]

        for scale in range(basescale, -1, -1):
            print('Scale', scale)
            tiles = 2**scale
            for y in range(tiles):
                for x in range(tiles):
                    ims = [
                        base[y * tilesize:(y + 1) * tilesize,
                             x * tilesize:(x + 1) * tilesize] for base in bases
                    ]
                    rgb = get_rgb(ims, bands, **rgbkwargs)
                    pp = patdata.copy()
                    pp.update(zoom=scale, x=x, y=y)
                    fn = pat % pp
                    trymakedirs(fn)
                    save_jpeg(fn, rgb)
                    print('Wrote', fn)

            for i, base in enumerate(bases):
                base = (base[::2, ::2] + base[1::2, ::2] + base[1::2, 1::2] +
                        base[::2, 1::2]) / 4.
                bases[i] = base

    elif opt.kind in [
            'unwise',
            'unwise-neo1',
            'unwise-w3w4',
    ]:
        import pylab as plt
        from decals import settings
        from map.views import _unwise_to_rgb, save_jpeg, trymakedirs
        import fitsio

        if opt.kind == 'unwise-w3w4':
            tag = 'unwise-w3w4'
            bands = [3, 4]
            bounce = _bounce_map_unwise_w3w4
        elif opt.kind == 'unwise-neo1':
            tag = 'unwise-neo1'
            bands = [1, 2]
            bounce = _bounce_map_unwise_neo1
        else:
            tag = 'unwise-w1w2'
            bands = [1, 2]
            bounce = _bounce_map_unwise_w1w2

        pat = os.path.join(settings.DATA_DIR, 'tiles', tag, '%(ver)s',
                           '%(zoom)i', '%(x)i', '%(y)i.jpg')
        ver = 1
        patdata = dict(ver=ver)

        basescale = 4

        tilesize = 256
        tiles = 2**basescale
        side = tiles * tilesize

        basepat = 'base-%s-%i-%%s.fits' % (opt.kind, basescale)
        basefns = [basepat % band for band in bands]

        if not all([os.path.exists(fn) for fn in basefns]):
            bases = [np.zeros((side, side), np.float32) for band in bands]

            args = []
            for y in range(tiles):
                for x in range(tiles):
                    #print 'Base tile', x, y
                    args.append((req, ver, basescale, x, y))
            tiles = mp.map(bounce, args)
            for ims, arg in zip(tiles, args):
                x, y = arg[-2:]
                for im, base in zip(ims, bases):
                    if im is None:
                        continue
                    base[y * tilesize:(y + 1) * tilesize,
                         x * tilesize:(x + 1) * tilesize] = im

            for fn, base in zip(basefns, bases):
                fitsio.write(fn, base, clobber=True)
        else:
            print('Reading', basefns)
            bases = [fitsio.read(fn) for fn in basefns]

            if False:
                # Messin' around
                plt.figure(figsize=(8, 8))
                plt.subplots_adjust(left=0, right=1, bottom=0, top=1)
                #for S in [1000, 3000, 10000]:
                #for Q in [10, 25, 50]:
                S, Q = 3000, 25
                im = _unwise_to_rgb([w1base, w2base], S=S, Q=Q)
                #plt.clf()
                #plt.imshow(im)
                plt.imsave('base-S%i-Q%s.png' % (S, Q), im)

                # Try converting to galactic coords...
                from astrometry.util.util import anwcs_create_mercator_2

                print('Base images:', w1base.shape)
                zoom = basescale
                h, w = w1base.shape
                zoomscale = 2.**zoom * (256. / h)
                print('Zoomscale', zoomscale)
                wcs = anwcs_create_mercator_2(180., 0., w / 2., h / 2.,
                                              zoomscale, w, h, 1)

                wcs2 = anwcs_create_mercator_2(0., 0., w / 2., h / 2.,
                                               zoomscale, w, h, 1)

                print('WCS:')
                for x, y in [(1, 1), (1, h), (w, 1), (w, h), (w / 2, 1),
                             (w / 2, h / 2)]:
                    print('x,y', (x, y), '-> RA,Dec',
                          wcs.pixelxy2radec(x, y)[-2:])

                ok, ras, nil = wcs2.pixelxy2radec(np.arange(w), np.ones(w))
                ok, nil, decs = wcs2.pixelxy2radec(np.ones(h), np.arange(h))
                print('RAs', ras.shape)
                print('Decs', decs.shape)

                lls = ras
                bbs = decs

                ll, bb = np.meshgrid(lls, bbs)
                print('LL,BB', ll.shape, bb.shape)

                from astrometry.util.starutil_numpy import lbtoradec

                ra, dec = lbtoradec(ll, bb)
                print('RA,Dec', ra.shape, dec.shape)

                ok, xx, yy = wcs.radec2pixelxy(ra, dec)
                print('xx,yy', xx.shape, yy.shape)

                lb1 = w1base[np.clip(np.round(yy - 1).astype(int), 0, h - 1),
                             np.clip(np.round(xx - 1).astype(int), 0, w - 1)]
                lb2 = w2base[np.clip(np.round(yy - 1).astype(int), 0, h - 1),
                             np.clip(np.round(xx - 1).astype(int), 0, w - 1)]

                lbim = _unwise_to_rgb(lb1, lb2, S=S, Q=Q)
                plt.imsave('lb.png', lbim)

                sys.exit(0)

        from scipy.ndimage.filters import gaussian_filter

        for scale in range(basescale - 1, -1, -1):

            for i, base in enumerate(bases):
                base = gaussian_filter(base, 1.)
                base = (base[::2, ::2] + base[1::2, ::2] + base[1::2, 1::2] +
                        base[::2, 1::2]) / 4.
                bases[i] = base

            tiles = 2**scale

            for y in range(tiles):
                for x in range(tiles):
                    ims = [
                        base[y * tilesize:(y + 1) * tilesize,
                             x * tilesize:(x + 1) * tilesize] for base in bases
                    ]
                    tile = _unwise_to_rgb(ims, bands=bands)
                    pp = patdata.copy()
                    pp.update(zoom=scale, x=x, y=y)
                    fn = pat % pp
                    trymakedirs(fn)
                    save_jpeg(fn, tile)
                    print('Wrote', fn)

    if opt.kind in ['depth-g', 'depth-r', 'depth-z']:
        import pylab as plt
        from decals import settings
        from scipy.ndimage.filters import gaussian_filter
        from map.views import trymakedirs

        tag = 'decam-' + opt.kind
        band = opt.kind[-1]
        ver = 1
        basescale = 5
        pat = os.path.join(settings.DATA_DIR, 'tiles', tag, '%(ver)s',
                           '%(zoom)i', '%(x)i', '%(y)i.jpg')
        patdata = dict(ver=ver)
        tilesize = 256
        tiles = 2**basescale
        side = tiles * tilesize

        base = np.zeros((side, side, 3), np.float32)
        for y in range(tiles):
            for x in range(tiles):
                dat = patdata.copy()
                dat.update(zoom=basescale, x=x, y=y)
                fn = pat % dat
                if not os.path.exists(fn):
                    print('Does not exist:', fn)
                    continue
                img = plt.imread(fn)
                base[y * tilesize:(y + 1) * tilesize,
                     x * tilesize:(x + 1) * tilesize, :] = img

        for scale in range(basescale - 1, -1, -1):

            newbase = []
            for i in range(3):
                b = gaussian_filter(base[:, :, i], 1.)
                b = (b[::2, ::2] + b[1::2, ::2] + b[1::2, 1::2] +
                     b[::2, 1::2]) / 4.
                newbase.append(b)
            base = np.dstack(newbase)

            tiles = 2**scale
            for y in range(tiles):
                for x in range(tiles):
                    img = base[y * tilesize:(y + 1) * tilesize,
                               x * tilesize:(x + 1) * tilesize, :]

                    pp = patdata.copy()
                    pp.update(zoom=scale, x=x, y=y)
                    fn = pat % pp
                    trymakedirs(fn)
                    plt.imsave(fn,
                               np.clip(np.round(img).astype(np.uint8), 0, 255))
                    print('Wrote', fn)

    ### HACK... factor this out...
    if opt.kind in [
            'sdss',
            'decals-dr2',
            'decals-dr2-model',
            'decals-dr2-resid',
            'decals-dr3',
            'decals-dr3-model',
            'decals-dr3-resid',
    ]:
        import pylab as plt
        from decals import settings
        from legacypipe.survey import get_rgb
        import fitsio
        from scipy.ndimage.filters import gaussian_filter
        from map.views import trymakedirs

        tag = opt.kind

        bouncemap = {
            'sdss': _bounce_sdssco,
            'decals-dr3': _bounce_decals_dr3,
            'decals-dr3-model': _bounce_decals_dr3,
            'decals-dr3-resid': _bounce_decals_dr3,
        }
        bounce = bouncemap[opt.kind]

        rgbkwargs = dict(mnmx=(-1, 100.), arcsinh=1.)

        bands = 'grz'
        if opt.kind in [
                'decals-dr2',
                'decals-dr2-model',
                'decals-dr3',
                'decals-dr3-model',
        ]:
            get_rgb = dr2_rgb
            rgbkwargs = {}
        elif opt.kind == 'sdssco':
            rgbfunc = sdss_rgb
            rgbkwargs = {}

        ver = tileversions.get(opt.kind, [1])[-1]
        print('Version', ver)
        basescale = 5

        pat = os.path.join(settings.DATA_DIR, 'tiles', tag, '%(ver)s',
                           '%(zoom)i', '%(x)i', '%(y)i.jpg')
        patdata = dict(ver=ver)

        tilesize = 256
        tiles = 2**basescale
        side = tiles * tilesize

        basepat = 'base-%s-%i-%%s.fits' % (opt.kind, basescale)

        basefns = [basepat % band for band in bands]
        if not all([os.path.exists(fn) for fn in basefns]):
            bases = [np.zeros((side, side), np.float32) for band in bands]

            args = []
            kwa = dict()
            if 'model' in opt.kind:
                kwa.update(model=True, add_gz=True)
            elif 'resid' in opt.kind:
                kwa.update(resid=True, model_gz=True)

            xy = []
            if opt.y1 is None:
                opt.y1 = tiles
            if opt.x0 is None:
                opt.x0 = 0
            if opt.x1 is None:
                opt.x1 = tiles
            for y in range(opt.y0, opt.y1):
                for x in range(opt.x0, opt.x1):
                    args.append(((req, ver, basescale, x, y), kwa))
                    xy.append((x, y))
            tiles = mp.map(bounce, args)
            for ims, (x, y) in zip(tiles, xy):
                if ims is None:
                    continue
                for im, base in zip(ims, bases):
                    if im is None:
                        continue
                    base[y * tilesize:(y + 1) * tilesize,
                         x * tilesize:(x + 1) * tilesize] = im

            for fn, base in zip(basefns, bases):
                fitsio.write(fn, base, clobber=True)
        else:
            print('Reading', basefns)
            bases = [fitsio.read(fn) for fn in basefns]

        #for scale in range(basescale-1, -1, -1):
        for scale in range(basescale, -1, -1):
            print('Scale', scale)
            tiles = 2**scale
            for y in range(tiles):
                for x in range(tiles):
                    ims = [
                        base[y * tilesize:(y + 1) * tilesize,
                             x * tilesize:(x + 1) * tilesize] for base in bases
                    ]

                    if opt.kind == 'sdss':
                        bands = 'gri'
                        rgb = sdss_rgb(ims, bands)
                    else:
                        rgb = get_rgb(ims, bands, **rgbkwargs)

                    pp = patdata.copy()
                    pp.update(zoom=scale, x=x, y=y)
                    fn = pat % pp
                    trymakedirs(fn)
                    save_jpeg(fn, rgb)
                    print('Wrote', fn)

            for i, base in enumerate(bases):
                #base = gaussian_filter(base, 1.)
                base = (base[::2, ::2] + base[1::2, ::2] + base[1::2, 1::2] +
                        base[::2, 1::2]) / 4.
                bases[i] = base
Exemple #4
0
def top_levels(mp, opt):
    if opt.kind in ['unwise', 'unwise-neo1', 'unwise-w3w4']:
        import pylab as plt
        from decals import settings
        from map.views import _unwise_to_rgb, save_jpeg, trymakedirs
        import fitsio

        if opt.kind == 'unwise-w3w4':
            tag = 'unwise-w3w4'
            bands = [3,4]
            bounce = _bounce_map_unwise_w3w4
        elif opt.kind == 'unwise-neo1':
            tag = 'unwise-neo1'
            bands = [1,2]
            bounce = _bounce_map_unwise_neo1
        else:
            tag = 'unwise-w1w2'
            bands = [1,2]
            bounce = _bounce_map_unwise_w1w2

        pat = os.path.join(settings.DATA_DIR, 'tiles', tag, '%(ver)s',
                           '%(zoom)i', '%(x)i', '%(y)i.jpg')
        ver = 1
        patdata = dict(ver=ver)

        basescale = 4

        tilesize = 256
        tiles = 2**basescale
        side = tiles * tilesize

        basepat = 'base-%s-%i-%%s.fits' % (opt.kind, basescale)
        basefns = [basepat % band for band in bands]

        if not all([os.path.exists(fn) for fn in basefns]):
            bases = [np.zeros((side, side), np.float32) for band in bands]

            args = []
            for y in range(tiles):
                for x in range(tiles):
                    #print 'Base tile', x, y
                    args.append((req, ver, basescale, x, y))
            tiles = mp.map(bounce, args)
            for ims,arg in zip(tiles,args):
                x,y = arg[-2:]
                for im,base in zip(ims, bases):
                    if im is None:
                        continue
                    base[y*tilesize:(y+1)*tilesize,
                         x*tilesize:(x+1)*tilesize] = im

            for fn,base in zip(basefns, bases):
                fitsio.write(fn, base, clobber=True)
        else:
            print 'Reading', basefns
            bases = [fitsio.read(fn) for fn in basefns]

            if False:
                # Messin' around
                plt.figure(figsize=(8,8))
                plt.subplots_adjust(left=0, right=1, bottom=0, top=1)
                #for S in [1000, 3000, 10000]:
                #for Q in [10, 25, 50]:
                S,Q = 3000,25
                im = _unwise_to_rgb([w1base, w2base], S=S, Q=Q)
                #plt.clf()
                #plt.imshow(im)
                plt.imsave('base-S%i-Q%s.png' % (S,Q), im)

                # Try converting to galactic coords...
                from astrometry.util.util import anwcs_create_mercator_2

                print 'Base images:', w1base.shape
                zoom = basescale
                h,w = w1base.shape
                zoomscale = 2.**zoom * (256./h)
                print 'Zoomscale', zoomscale
                wcs = anwcs_create_mercator_2(180., 0., w/2., h/2.,
                                              zoomscale, w, h, 1)

                wcs2 = anwcs_create_mercator_2(0., 0., w/2., h/2.,
                                               zoomscale, w, h, 1)

                print 'WCS:'
                for x,y in [(1,1), (1,h), (w,1), (w,h), (w/2,1), (w/2,h/2)]:
                    print 'x,y', (x,y), '-> RA,Dec', wcs.pixelxy2radec(x,y)[-2:]

                ok,ras,nil  = wcs2.pixelxy2radec(np.arange(w), np.ones(w))
                ok,nil,decs = wcs2.pixelxy2radec(np.ones(h), np.arange(h))
                print 'RAs', ras.shape
                print 'Decs', decs.shape

                lls = ras
                bbs = decs

                ll,bb = np.meshgrid(lls, bbs)
                print 'LL,BB', ll.shape, bb.shape

                from astrometry.util.starutil_numpy import lbtoradec

                ra,dec = lbtoradec(ll,bb)
                print 'RA,Dec', ra.shape, dec.shape

                ok,xx,yy = wcs.radec2pixelxy(ra, dec)
                print 'xx,yy', xx.shape, yy.shape

                lb1 = w1base[np.clip(np.round(yy-1).astype(int), 0, h-1),
                             np.clip(np.round(xx-1).astype(int), 0, w-1)]
                lb2 = w2base[np.clip(np.round(yy-1).astype(int), 0, h-1),
                             np.clip(np.round(xx-1).astype(int), 0, w-1)]

                lbim = _unwise_to_rgb(lb1, lb2, S=S,Q=Q)
                plt.imsave('lb.png', lbim)

                sys.exit(0)

        from scipy.ndimage.filters import gaussian_filter

        for scale in range(basescale-1, -1, -1):

            for i,base in enumerate(bases):
                base = gaussian_filter(base, 1.)
                base = (base[::2,::2] + base[1::2,::2] + base[1::2,1::2] + base[::2,1::2])/4.
                bases[i] = base

            tiles = 2**scale
            
            for y in range(tiles):
                for x in range(tiles):
                    ims = [base[y*tilesize:(y+1)*tilesize,
                                x*tilesize:(x+1)*tilesize] for base in bases]
                    tile = _unwise_to_rgb(ims, bands=bands)
                    pp = patdata.copy()
                    pp.update(zoom=scale, x=x, y=y)
                    fn = pat % pp
                    trymakedirs(fn)
                    save_jpeg(fn, tile)
                    print 'Wrote', fn


    if opt.kind in ['depth-g', 'depth-r', 'depth-z']:
        import pylab as plt
        from decals import settings
        from scipy.ndimage.filters import gaussian_filter
        from map.views import trymakedirs

        tag = 'decam-' + opt.kind
        band = opt.kind[-1]
        ver = 1
        basescale = 5
        pat = os.path.join(settings.DATA_DIR, 'tiles', tag, '%(ver)s',
                           '%(zoom)i', '%(x)i', '%(y)i.jpg')
        patdata = dict(ver=ver)
        tilesize = 256
        tiles = 2**basescale
        side = tiles * tilesize
        
        base = np.zeros((side, side, 3), np.float32)
        for y in range(tiles):
            for x in range(tiles):
                dat = patdata.copy()
                dat.update(zoom=basescale, x=x, y=y)
                fn = pat % dat
                if not os.path.exists(fn):
                    print 'Does not exist:', fn
                    continue
                img = plt.imread(fn)
                base[y*tilesize:(y+1)*tilesize,
                     x*tilesize:(x+1)*tilesize,:] = img

        for scale in range(basescale-1, -1, -1):

            newbase = []
            for i in range(3):
                b = gaussian_filter(base[:,:,i], 1.)
                b = (b[ ::2, ::2] + b[1::2, ::2] +
                     b[1::2,1::2] + b[ ::2,1::2])/4.
                newbase.append(b)
            base = np.dstack(newbase)

            tiles = 2**scale
            for y in range(tiles):
                for x in range(tiles):
                    img = base[y*tilesize:(y+1)*tilesize,
                               x*tilesize:(x+1)*tilesize, :]

                    pp = patdata.copy()
                    pp.update(zoom=scale, x=x, y=y)
                    fn = pat % pp
                    trymakedirs(fn)
                    plt.imsave(fn, np.clip(np.round(img).astype(np.uint8), 0, 255))
                    print 'Wrote', fn


    ### HACK... factor this out...
    if opt.kind in ['image', 'model', 'resid', 'image-dr1k', 'sdss',
                    'decals-dr2', 'decals-dr2-model', 'decals-dr2-resid']:
        import pylab as plt
        from decals import settings
        from legacypipe.common import get_rgb
        import fitsio
        from scipy.ndimage.filters import gaussian_filter
        from map.views import trymakedirs

        tagdict = dict(image='decals-dr1j', model='decals-model-dr1j',
                       resid='decals-resid-dr1j')
        tag = tagdict.get(opt.kind, opt.kind)
        del tagdict

        bouncemap = {
            #'sdss': _bounce_sdss,
            'sdss': _bounce_sdssco,
            'decals-dr2': _bounce_decals_dr2,
            'decals-dr2-model': _bounce_decals_dr2,
            'decals-dr2-resid': _bounce_decals_dr2,
            }
        bounce = bouncemap[opt.kind]

        rgbkwargs = dict(mnmx=(-1,100.), arcsinh=1.)

        if opt.kind in ['decals-dr2', 'decals-dr2-model']:
            get_rgb = dr2_rgb
            rgbkwargs = {}
        elif opt.kind == 'sdssco':
            rgbfunc=sdss_rgb
            rgbkwargs = {}

        ver = tileversions.get(opt.kind, [1])[-1]
        print 'Version', ver
        basescale = 5

        pat = os.path.join(settings.DATA_DIR, 'tiles', tag, '%(ver)s',
                           '%(zoom)i', '%(x)i', '%(y)i.jpg')
        patdata = dict(ver=ver)

        tilesize = 256
        tiles = 2**basescale
        side = tiles * tilesize

        basepat = 'base-%s-%i-%%s.fits' % (opt.kind, basescale)
        bands = 'grz'

        basefns = [basepat % band for band in bands]
        if not all([os.path.exists(fn) for fn in basefns]):
            bases = [np.zeros((side, side), np.float32) for band in bands]

            args = []
            kwa = dict()
            if 'model' in opt.kind:
                kwa.update(model=True, add_gz=True)
            elif 'resid' in opt.kind:
                kwa.update(resid=True, model_gz=True)

            xy = []
            if opt.y1 is None:
                opt.y1 = tiles
            if opt.x0 is None:
                opt.x0 = 0
            if opt.x1 is None:
                opt.x1 = tiles
            for y in range(opt.y0, opt.y1):
                for x in range(opt.x0, opt.x1):
                    args.append(((req, ver, basescale, x, y),kwa))
                    xy.append((x,y))
            tiles = mp.map(bounce, args)
            for ims,(x,y) in zip(tiles, xy):
                if ims is None:
                    continue
                for im,base in zip(ims, bases):
                    if im is None:
                        continue
                    base[y*tilesize:(y+1)*tilesize,
                         x*tilesize:(x+1)*tilesize] = im

            for fn,base in zip(basefns, bases):
                fitsio.write(fn, base, clobber=True)
        else:
            print 'Reading', basefns
            bases = [fitsio.read(fn) for fn in basefns]

        for scale in range(basescale-1, -1, -1):
            print 'Scale', scale
            for i,base in enumerate(bases):
                #base = gaussian_filter(base, 1.)
                base = (base[::2,::2] + base[1::2,::2] + base[1::2,1::2] + base[::2,1::2])/4.
                bases[i] = base

            tiles = 2**scale
            for y in range(tiles):
                for x in range(tiles):
                    ims = [base[y*tilesize:(y+1)*tilesize,
                                x*tilesize:(x+1)*tilesize] for base in bases]

                    if opt.kind == 'sdss':
                        bands = 'gri'
                        rgb = sdss_rgb(ims, bands)
                    else:
                        rgb = get_rgb(ims, bands, **rgbkwargs)

                    pp = patdata.copy()
                    pp.update(zoom=scale, x=x, y=y)
                    fn = pat % pp
                    trymakedirs(fn)
                    save_jpeg(fn, rgb)
                    print 'Wrote', fn