Example #1
0
def match_kdtree_catalog(wcs, catfn):
    from astrometry.libkd.spherematch import (
        tree_open,
        tree_close,
        tree_build_radec,
        tree_free,
        trees_match,
        tree_permute,
    )
    from astrometry.libkd import spherematch_c
    from astrometry.util.starutil_numpy import deg2dist, xyztoradec
    import numpy as np
    import sys

    rc, dc = wcs.get_center()
    rr = wcs.get_radius()
    kd = tree_open(catfn)
    kd2 = tree_build_radec(np.array([rc]), np.array([dc]))
    r = deg2dist(rr)
    I, J, nil = trees_match(kd, kd2, r, permuted=False)
    # HACK
    # I2,J,d = trees_match(kd, kd2, r)
    xyz = spherematch_c.kdtree_get_positions(kd, I.astype(np.uint32))
    # print 'I', I
    I2 = tree_permute(kd, I)
    # print 'I2', I2
    tree_free(kd2)
    tree_close(kd)
    tra, tdec = xyztoradec(xyz)
    return tra, tdec, I2
Example #2
0
    def other_passes(self, tile, tiles):
        '''
        Given tile number *tile*, return the obstatus rows for the other passes
        on this tile center.

        Returns: *otherpasses*, table object
        '''
        if tiles != self.tiles:
            from astrometry.libkd.spherematch import match_radec
            # Could also use the fact that the passes are offset from each other
            # by a fixed index (15872 for decam)...
            # Max separation is about 0.6 degrees for DECam...
            #### FIXME for Mosaic this is much smaller... and the three passes
            #### for a tile are not necessarily relatively close to each other.
            I,J,d = match_radec(tile.ra, tile.dec, tiles.ra, tiles.dec, 1.)
            # Omit 'tile' itself...
            K = np.flatnonzero(tiles.tileid[J] != tile.tileid)
            J = J[K]
            return tiles[J]

        if self.tiletree is None:
            from astrometry.libkd.spherematch import tree_build_radec
            self.tiletree = tree_build_radec(self.tiles.ra, self.tiles.dec)

        from astrometry.libkd.spherematch import tree_search_radec
        J = tree_search_radec(self.tiletree, tile.ra, tile.dec, 1.0)
        # Omit 'tile' itself...
        K = np.flatnonzero(tiles.tileid[J] != tile.tileid)
        J = J[K]
        return tiles[J]
Example #3
0
def _match_tile(X):
    tid, tile_ra, tile_dec, tile_obstime, tile_theta, tile_obsha, match_radius = X

    loc_ra, loc_dec = xy2radec(hw, tile_ra, tile_dec, tile_obstime, tile_theta,
                               tile_obsha, stuck_x, stuck_y, False, 0)
    kd = tree_build_radec(loc_ra, loc_dec)
    I, J, d = trees_match(starkd, kd, match_radius)
    print('Tile', tid, 'matched', len(I), 'stars')
    if len(I):
        res = tid, I, loc_ra[J], loc_dec[J], stuck_loc[J], np.rad2deg(
            d) * 3600.
    else:
        res = None
    return res
Example #4
0
def match_kdtree_catalog(wcs, catfn):
    from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match, tree_permute
    from astrometry.libkd import spherematch_c
    from astrometry.util.starutil_numpy import deg2dist, xyztoradec
    import numpy as np
    import sys

    rc,dc = wcs.get_center()
    rr = wcs.get_radius()
    kd = tree_open(catfn)
    kd2 = tree_build_radec(np.array([rc]), np.array([dc]))
    r = deg2dist(rr)
    I,J,nil = trees_match(kd, kd2, r, permuted=False)
    del kd2
    xyz = kd.get_data(I.astype(np.uint32))
    I = kd.permute(I)
    del kd
    tra,tdec = xyztoradec(xyz)
    return tra, tdec, I
Example #5
0
def match_kdtree_catalog(wcs, catfn):
    from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match, tree_permute
    from astrometry.libkd import spherematch_c
    from astrometry.util.starutil_numpy import deg2dist, xyztoradec
    import numpy as np
    import sys

    rc,dc = wcs.get_center()
    rr = wcs.get_radius()
    kd = tree_open(catfn)
    kd2 = tree_build_radec(np.array([rc]), np.array([dc]))
    r = deg2dist(rr)
    I,J,nil = trees_match(kd, kd2, r, permuted=False)
    del kd2
    xyz = kd.get_data(I.astype(np.uint32))
    I = kd.permute(I)
    del kd
    tra,tdec = xyztoradec(xyz)
    return tra, tdec, I
Example #6
0
    def bricks_touching_radec_box(self, bricks,
                                  ralo, rahi, declo, dechi):
        '''
        Returns an index vector of the bricks that touch the given RA,Dec box.
        '''
        if bricks is None:
            bricks = self.get_bricks_readonly()
        if self.cache_tree and bricks == self.bricks:
            from astrometry.libkd.spherematch import tree_build_radec, tree_search_radec
            # Use kdtree
            if self.bricktree is None:
                self.bricktree = tree_build_radec(bricks.ra, bricks.dec)
            # brick size
            radius = np.sqrt(2.)/2. * self.bricksize
            # + RA,Dec box size
            radius = radius + degrees_between(ralo, declo, rahi, dechi) / 2.
            dec = (dechi + declo) / 2.
            c = (np.cos(np.deg2rad(rahi)) + np.cos(np.deg2rad(ralo))) / 2.
            s = (np.sin(np.deg2rad(rahi)) + np.sin(np.deg2rad(ralo))) / 2.
            ra  = np.rad2deg(np.arctan2(s, c))
            J = tree_search_radec(self.bricktree, ra, dec, radius)
            I = J[np.nonzero((bricks.ra1[J]  <= rahi ) * (bricks.ra2[J]  >= ralo) *
                             (bricks.dec1[J] <= dechi) * (bricks.dec2[J] >= declo))[0]]
            return I

        if rahi < ralo:
            # Wrap-around
            print('In Dec slice:', len(np.flatnonzero((bricks.dec1 <= dechi) *
                                                      (bricks.dec2 >= declo))))
            print('Above RAlo=', ralo, ':', len(np.flatnonzero(bricks.ra2 >= ralo)))
            print('Below RAhi=', rahi, ':', len(np.flatnonzero(bricks.ra1 <= rahi)))
            print('In RA slice:', len(np.nonzero(np.logical_or(bricks.ra2 >= ralo,
                                                               bricks.ra1 <= rahi))))
                    
            I, = np.nonzero(np.logical_or(bricks.ra2 >= ralo, bricks.ra1 <= rahi) *
                            (bricks.dec1 <= dechi) * (bricks.dec2 >= declo))
            print('In RA&Dec slice', len(I))
        else:
            I, = np.nonzero((bricks.ra1  <= rahi ) * (bricks.ra2  >= ralo) *
                            (bricks.dec1 <= dechi) * (bricks.dec2 >= declo))
        return I
Example #7
0
    def bricks_touching_radec_box(self, bricks,
                                  ralo, rahi, declo, dechi):
        '''
        Returns an index vector of the bricks that touch the given RA,Dec box.
        '''
        if bricks is None:
            bricks = self.get_bricks_readonly()
        if self.cache_tree and bricks == self.bricks:
            from astrometry.libkd.spherematch import tree_build_radec, tree_search_radec
            # Use kdtree
            if self.bricktree is None:
                self.bricktree = tree_build_radec(bricks.ra, bricks.dec)
            # brick size
            radius = np.sqrt(2.)/2. * self.bricksize
            # + RA,Dec box size
            radius = radius + degrees_between(ralo, declo, rahi, dechi) / 2.
            dec = (dechi + declo) / 2.
            c = (np.cos(np.deg2rad(rahi)) + np.cos(np.deg2rad(ralo))) / 2.
            s = (np.sin(np.deg2rad(rahi)) + np.sin(np.deg2rad(ralo))) / 2.
            ra  = np.rad2deg(np.arctan2(s, c))
            J = tree_search_radec(self.bricktree, ra, dec, radius)
            I = J[np.nonzero((bricks.ra1[J]  <= rahi ) * (bricks.ra2[J]  >= ralo) *
                             (bricks.dec1[J] <= dechi) * (bricks.dec2[J] >= declo))[0]]
            return I

        if rahi < ralo:
            # Wrap-around
            print('In Dec slice:', len(np.flatnonzero((bricks.dec1 <= dechi) *
                                                      (bricks.dec2 >= declo))))
            print('Above RAlo=', ralo, ':', len(np.flatnonzero(bricks.ra2 >= ralo)))
            print('Below RAhi=', rahi, ':', len(np.flatnonzero(bricks.ra1 <= rahi)))
            print('In RA slice:', len(np.nonzero(np.logical_or(bricks.ra2 >= ralo,
                                                               bricks.ra1 <= rahi))))
                    
            I, = np.nonzero(np.logical_or(bricks.ra2 >= ralo, bricks.ra1 <= rahi) *
                            (bricks.dec1 <= dechi) * (bricks.dec2 >= declo))
            print('In RA&Dec slice', len(I))
        else:
            I, = np.nonzero((bricks.ra1  <= rahi ) * (bricks.ra2  >= ralo) *
                            (bricks.dec1 <= dechi) * (bricks.dec2 >= declo))
        return I
Example #8
0
def match_kdtree_catalog(wcs, catfn):
    from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match, tree_permute
    from astrometry.libkd import spherematch_c
    from astrometry.util.starutil_numpy import deg2dist, xyztoradec
    import numpy as np
    import sys

    rc, dc = wcs.get_center()
    rr = wcs.get_radius()
    kd = tree_open(catfn)
    kd2 = tree_build_radec(np.array([rc]), np.array([dc]))
    r = deg2dist(rr)
    I, J, nil = trees_match(kd, kd2, r, permuted=False)
    # HACK
    #I2,J,d = trees_match(kd, kd2, r)
    xyz = spherematch_c.kdtree_get_positions(kd, I.astype(np.uint32))
    #print 'I', I
    I2 = tree_permute(kd, I)
    #print 'I2', I2
    tree_free(kd2)
    tree_close(kd)
    tra, tdec = xyztoradec(xyz)
    return tra, tdec, I2
Example #9
0
def plot_wcs_outline(wcsfn,
                     plotfn,
                     W=256,
                     H=256,
                     width=36,
                     zoom=True,
                     zoomwidth=3.6,
                     grid=10,
                     hd=False,
                     hd_labels=False,
                     tycho2=False):
    anutil.log_init(3)
    #anutil.log_set_level(3)

    wcs = anutil.Tan(wcsfn, 0)
    ra, dec = wcs.radec_center()

    plot = ps.Plotstuff(outformat='png', size=(W, H), rdw=(ra, dec, width))
    plot.linestep = 1.
    plot.color = 'verydarkblue'
    plot.plot('fill')

    plot.fontsize = 12
    #plot.color = 'gray'
    # dark gray
    plot.rgb = (0.3, 0.3, 0.3)
    if grid is not None:
        plot.plot_grid(*([grid] * 4))

    plot.rgb = (0.4, 0.6, 0.4)
    ann = plot.annotations
    ann.NGC = ann.bright = ann.HD = 0
    ann.constellations = 1
    ann.constellation_labels = 1
    ann.constellation_labels_long = 1
    plot.plot('annotations')
    plot.stroke()
    ann.constellation_labels = 0
    ann.constellation_labels_long = 0
    ann.constellation_lines = 0

    ann.constellation_markers = 1
    plot.markersize = 3
    plot.rgb = (0.4, 0.6, 0.4)
    plot.plot('annotations')
    plot.fill()
    ann.constellation_markers = 0

    ann.bright_labels = False
    ann.bright = True
    plot.markersize = 2
    if zoom >= 2:
        ann.bright_labels = True
    plot.plot('annotations')
    ann.bright = False
    ann.bright_labels = False
    plot.fill()

    if hd:
        ann.HD = True
        ann.HD_labels = hd_labels
        ps.plot_annotations_set_hd_catalog(ann, settings.HENRY_DRAPER_CAT)
        plot.plot('annotations')
        plot.stroke()
        ann.HD = False
        ann.HD_labels = False

    if tycho2 and settings.TYCHO2_KD:
        from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match
        from astrometry.libkd import spherematch_c
        from astrometry.util.starutil_numpy import deg2dist, xyztoradec
        import numpy as np
        import sys
        kd = tree_open(settings.TYCHO2_KD)
        # this is a bit silly: build a tree with a single point, then do match()
        kd2 = tree_build_radec(np.array([ra]), np.array([dec]))
        r = deg2dist(width * np.sqrt(2.) / 2.)
        #r = deg2dist(wcs.radius())
        I, nil, nil = trees_match(kd, kd2, r, permuted=False)
        del nil
        #print 'Matched', len(I)
        xyz = spherematch_c.kdtree_get_positions(kd, I)
        del I
        tree_free(kd2)
        tree_close(kd)
        #print >>sys.stderr, 'Got', xyz.shape, xyz
        tra, tdec = xyztoradec(xyz)
        #print >>sys.stderr, 'RA,Dec', ra,dec
        plot.apply_settings()
        for r, d in zip(tra, tdec):
            plot.marker_radec(r, d)
        plot.fill()

    ann.NGC = 1
    plot.plot('annotations')
    ann.NGC = 0

    plot.color = 'white'
    plot.lw = 3
    out = plot.outline
    out.wcs_file = wcsfn
    plot.plot('outline')

    if zoom:
        # MAGIC width, height are arbitrary
        zoomwcs = anutil.anwcs_create_box(ra, dec, zoomwidth, 1000, 1000)
        out.wcs = zoomwcs
        plot.lw = 1
        plot.dashed(3)
        plot.plot('outline')

    plot.write(plotfn)
print('Kd bounding-box:', spherematch.tree_bbox(kd))

print('Kd bounding-box:', kd.bbox)

print('Kd data:', spherematch.tree_data(kd, np.array([0,3,5]).astype(np.uint32)))

print('Kd data:', kd.get_data(np.array([0,3,5]).astype(np.uint32)))

print('Permute:', spherematch.tree_permute(kd, np.array([3,5,7]).astype(np.int32)))

print('Permute:', kd.permute(np.array([0,99,199]).astype(np.int32)))

ra,dec = np.meshgrid(np.arange(0, 360), np.arange(-90, 91, 1))
ra1 = ra.ravel()
dec1 = dec.ravel()
rdkd1 = spherematch.tree_build_radec(ra1, dec1)
print('RdKd:', rdkd1.n, rdkd1.bbox)

ra2  = np.random.uniform(-10, 10, size=1000)
dec2 = np.random.uniform(-10, 10, size=1000)
rdkd2 = spherematch.tree_build_radec(ra2, dec2)

I = spherematch.tree_search_radec(rdkd1, ra2[0], dec2[0], 2.)
print('search_radec:', I)

I,J,d = spherematch.match_radec(ra1, dec1, ra2, dec2, 1.)
print('Matches:', len(I))

I,J,d = spherematch.match_radec(ra1, dec1, ra2, dec2, 1., nearest=True)
print('Nearest matches:', len(I))
Example #11
0
		for i in range(len(T)):
			if not plot.wcs.is_inside(T.ra[i], T.dec[i]):
				continue
			ann.add_target(T.ra[i], T.dec[i], 'Abell %i' % T.aco[i])

	if opt.t2cat:
		from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match
		from astrometry.libkd import spherematch_c
		from astrometry.util.starutil_numpy import deg2dist, xyztoradec
		import numpy as np
		import sys
		wcs = plot.wcs
		rc,dc = wcs.get_center()
		rr = wcs.get_radius()
		kd = tree_open(opt.t2cat)
		kd2 = tree_build_radec(np.array([rc]), np.array([dc]))
		r = deg2dist(rr)
		I,J,d = trees_match(kd, kd2, r, permuted=False)
		# HACK
		I2,J,d = trees_match(kd, kd2, r)
		xyz = spherematch_c.kdtree_get_positions(kd, I)
		tree_free(kd2)
		tree_close(kd)
		tra,tdec = xyztoradec(xyz)
		T = fits_table(opt.t2cat, hdu=6)
		for r,d,t1,t2,t3 in zip(tra,tdec, T.tyc1[I2], T.tyc2[I2], T.tyc3[I2]):
			if not plot.wcs.is_inside(r, d):
				continue
			ann.add_target(r, d, 'Tycho-2 %i-%i-%i' % (t1,t2,t3))

			
print('Kd bounding-box:', spherematch.tree_bbox(kd))

print('Kd bounding-box:', kd.bbox)

print('Kd data:', spherematch.tree_data(kd, np.array([0,3,5]).astype(np.uint32)))

print('Kd data:', kd.get_data(np.array([0,3,5]).astype(np.uint32)))

print('Permute:', spherematch.tree_permute(kd, np.array([3,5,7]).astype(np.int32)))

print('Permute:', kd.permute(np.array([0,99,199]).astype(np.int32)))

ra,dec = np.meshgrid(np.arange(0, 360), np.arange(-90, 91, 1))
ra1 = ra.ravel()
dec1 = dec.ravel()
rdkd1 = spherematch.tree_build_radec(ra1, dec1)
print('RdKd:', rdkd1.n, rdkd1.bbox)

ra2  = np.random.uniform(-10, 10, size=1000)
dec2 = np.random.uniform(-10, 10, size=1000)
rdkd2 = spherematch.tree_build_radec(ra2, dec2)

I = spherematch.tree_search_radec(rdkd1, ra2[0], dec2[0], 2.)
print('search_radec:', I)

I,J,d = spherematch.match_radec(ra1, dec1, ra2, dec2, 1.)
print('Matches:', len(I))

I,J,d = spherematch.match_radec(ra1, dec1, ra2, dec2, 1., nearest=True)
print('Nearest matches:', len(I))
Example #13
0
def map_decam_depth(req,
                    ver,
                    zoom,
                    x,
                    y,
                    savecache=False,
                    band=None,
                    ignoreCached=False):
    global Tdepth
    global Tdepthkd

    if band is None:
        band = req.GET.get('band')
    if not band in ['g', 'r', 'z']:
        raise RuntimeError('Invalid band')
    tag = 'decam-depth-%s' % band
    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:
        print('Cached:', tilefn)
        return send_file(tilefn,
                         'image/jpeg',
                         expires=oneyear,
                         modsince=req.META.get('HTTP_IF_MODIFIED_SINCE'))
    from astrometry.util.util import Tan
    from astrometry.libkd.spherematch import match_radec
    from astrometry.libkd.spherematch import tree_build_radec, tree_search_radec
    from astrometry.util.fits import fits_table
    from astrometry.util.starutil_numpy import degrees_between
    import numpy as np
    import fitsio
    try:
        wcs, W, H, zoomscale, zoom, x, y = get_tile_wcs(zoom, x, y)
    except RuntimeError as e:
        return HttpResponse(e.strerror)
    rlo, d = wcs.pixelxy2radec(W, H / 2)[-2:]
    rhi, d = wcs.pixelxy2radec(1, H / 2)[-2:]
    r, d1 = wcs.pixelxy2radec(W / 2, 1)[-2:]
    r, d2 = wcs.pixelxy2radec(W / 2, H)[-2:]

    r, d = wcs.pixelxy2radec(W / 2, H / 2)[-2:]
    rad = max(degrees_between(r, d, rlo, d1), degrees_between(r, d, rhi, d2))

    if Tdepth is None:
        T = fits_table(os.path.join(basedir, 'decals-zpt-nondecals.fits'),
                       columns=[
                           'ccdra', 'ccddec', 'arawgain', 'avsky', 'ccdzpt',
                           'filter', 'crpix1', 'crpix2', 'crval1', 'crval2',
                           'cd1_1', 'cd1_2', 'cd2_1', 'cd2_2', 'naxis1',
                           'naxis2', 'exptime', 'fwhm'
                       ])
        T.rename('ccdra', 'ra')
        T.rename('ccddec', 'dec')

        Tdepth = {}
        Tdepthkd = {}
        for b in ['g', 'r', 'z']:
            Tdepth[b] = T[T.filter == b]
            Tdepthkd[b] = tree_build_radec(Tdepth[b].ra, Tdepth[b].dec)

    T = Tdepth[band]
    Tkd = Tdepthkd[band]

    #I,J,d = match_radec(T.ra, T.dec, r, d, rad + 0.2)
    I = tree_search_radec(Tkd, r, d, rad + 0.2)
    print(len(I), 'CCDs in range')
    if len(I) == 0:
        from django.http import HttpResponseRedirect
        return HttpResponseRedirect(settings.STATIC_URL + 'blank.jpg')

    depthiv = np.zeros((H, W), np.float32)
    for t in T[I]:
        twcs = Tan(*[
            float(x) for x in [
                t.crval1, t.crval2, t.crpix1, t.crpix2, t.cd1_1, t.cd1_2,
                t.cd2_1, t.cd2_2, t.naxis1, t.naxis2
            ]
        ])
        w, h = t.naxis1, t.naxis2
        r, d = twcs.pixelxy2radec([1, 1, w, w], [1, h, h, 1])
        ok, x, y = wcs.radec2pixelxy(r, d)
        #print 'x,y coords of CCD:', x, y
        x0 = int(x.min())
        x1 = int(x.max())
        y0 = int(y.min())
        y1 = int(y.max())
        if y1 < 0 or x1 < 0 or x0 >= W or y0 >= H:
            continue

        readnoise = 10.  # e-; 7.0 to 15.0 according to DECam Data Handbook
        skysig = np.sqrt(t.avsky * t.arawgain + readnoise**2) / t.arawgain
        zpscale = 10.**((t.ccdzpt - 22.5) / 2.5) * t.exptime
        sig1 = skysig / zpscale
        psf_sigma = t.fwhm / 2.35
        # point-source depth
        psfnorm = 1. / (2. * np.sqrt(np.pi) * psf_sigma)
        detsig1 = sig1 / psfnorm

        #print '5-sigma point-source depth:', NanoMaggies.nanomaggiesToMag(detsig1 * 5.)

        div = 1 / detsig1**2
        depthiv[max(y0, 0):min(y1, H), max(x0, 0):min(x1, W)] += div

    ptsrc = -2.5 * (np.log10(np.sqrt(1. / depthiv) * 5) - 9)
    ptsrc[depthiv == 0] = 0.

    if savecache:
        trymakedirs(tilefn)
    else:
        import tempfile
        f, tilefn = tempfile.mkstemp(suffix='.jpg')
        os.close(f)

    import pylab as plt
    plt.imsave(tilefn, ptsrc, vmin=22., vmax=25., cmap='hot')  #nipy_spectral')

    return send_file(tilefn, 'image/jpeg', unlink=(not savecache))
Example #14
0
def plot_wcs_outline(wcsfn, plotfn, W=256, H=256, width=36, zoom=True,
                     zoomwidth=3.6, grid=10, hd=False, hd_labels=False,
                     tycho2=False):
    anutil.log_init(3)
    #anutil.log_set_level(3)

    wcs = anutil.Tan(wcsfn, 0)
    ra,dec = wcs.radec_center()

    plot = ps.Plotstuff(outformat='png', size=(W, H), rdw=(ra,dec,width))
    plot.linestep = 1.
    plot.color = 'verydarkblue'
    plot.plot('fill')

    plot.fontsize = 12
    #plot.color = 'gray'
    # dark gray
    plot.rgb = (0.3,0.3,0.3)
    if grid is not None:
        plot.plot_grid(*([grid]*4))

    plot.rgb = (0.4, 0.6, 0.4)
    ann = plot.annotations
    ann.NGC = ann.bright = ann.HD = 0
    ann.constellations = 1
    ann.constellation_labels = 1
    ann.constellation_labels_long = 1
    plot.plot('annotations')
    plot.stroke()
    ann.constellation_labels = 0
    ann.constellation_labels_long = 0
    ann.constellation_lines = 0

    ann.constellation_markers = 1
    plot.markersize = 3
    plot.rgb = (0.4, 0.6, 0.4)
    plot.plot('annotations')
    plot.fill()
    ann.constellation_markers = 0

    ann.bright_labels = False
    ann.bright = True
    plot.markersize = 2
    if zoom >= 2:
        ann.bright_labels = True
    plot.plot('annotations')
    ann.bright = False
    ann.bright_labels = False
    plot.fill()

    if hd:
        ann.HD = True
        ann.HD_labels = hd_labels
        ps.plot_annotations_set_hd_catalog(ann, settings.HENRY_DRAPER_CAT)
        plot.plot('annotations')
        plot.stroke()
        ann.HD = False
        ann.HD_labels = False

    if tycho2:
        from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match
        from astrometry.libkd import spherematch_c
        from astrometry.util.starutil_numpy import deg2dist, xyztoradec
        import numpy as np
        import sys
        kd = tree_open(settings.TYCHO2_KD)
        # this is a bit silly: build a tree with a single point, then do match()
        kd2 = tree_build_radec(np.array([ra]), np.array([dec]))
        r = deg2dist(width * np.sqrt(2.) / 2.)
        #r = deg2dist(wcs.radius())
        I,J,d = trees_match(kd, kd2, r, permuted=False)
        del J
        del d
        #print 'Matched', len(I)
        xyz = spherematch_c.kdtree_get_positions(kd, I)
        del I
        tree_free(kd2)
        tree_close(kd)
        #print >>sys.stderr, 'Got', xyz.shape, xyz
        tra,tdec = xyztoradec(xyz)
        #print >>sys.stderr, 'RA,Dec', ra,dec
        plot.apply_settings()
        for r,d in zip(tra,tdec):
            plot.marker_radec(r,d)
        plot.fill()

    ann.NGC = 1
    plot.plot('annotations')
    ann.NGC = 0

    plot.color = 'white'
    plot.lw = 3
    out = plot.outline
    out.wcs_file = wcsfn
    plot.plot('outline')

    if zoom:
        # MAGIC width, height are arbitrary
        zoomwcs = anutil.anwcs_create_box(ra, dec, zoomwidth, 1000,1000)
        out.wcs = zoomwcs
        plot.lw = 1
        plot.dashed(3)
        plot.plot('outline')

    plot.write(plotfn)
 def get_healpix_tree(self, healpix):
     from astrometry.util.fits import fits_table
     fname = self.fnpattern % dict(hp=healpix)
     tab = fits_table(fname, columns=self.columns)
     kd = tree_build_radec(tab.ra, tab.dec)
     return (kd, tab)
Example #16
0
            wcs.write_to(base + '-wcs.fits')

        #bomb()
        fns = keepfns

    names = [fn.replace('-bright.fits', '') for fn in fns]

    outlines = [getwcsoutline(wcs) for wcs in WCS]

    overlaps, areas = find_overlaps(outlines)

    print('Reading tables...')
    TT = [fits_table(fn) for fn in fns]
    print('Building trees...')
    kds = [tree_build_radec(T.ra, T.dec) for T in TT]

    for T, name in zip(TT, names):
        T.name = np.array([name] * len(T))

    allra = np.hstack([T.ra for T in TT])
    alldec = np.hstack([T.dec for T in TT])
    minra = np.min(allra)
    maxra = np.max(allra)
    mindec = np.min(alldec)
    maxdec = np.max(alldec)

    print('RA,Dec range:', minra, maxra, mindec, maxdec)

    plothist(allra, alldec)
    plt.axis([maxra, minra, mindec, maxdec])
Example #17
0
def map_decam_depth(req, ver, zoom, x, y, savecache=False, band=None,
                    ignoreCached=False):
    global Tdepth
    global Tdepthkd

    if band is None:
        band = req.GET.get('band')
    if not band in ['g','r','z']:
        raise RuntimeError('Invalid band')
    tag = 'decam-depth-%s' % band
    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:
        print 'Cached:', tilefn
        return send_file(tilefn, 'image/jpeg', expires=oneyear,
                         modsince=req.META.get('HTTP_IF_MODIFIED_SINCE'))
    from astrometry.util.util import Tan
    from astrometry.libkd.spherematch import match_radec
    from astrometry.libkd.spherematch import tree_build_radec, tree_search_radec
    from astrometry.util.fits import fits_table
    from astrometry.util.starutil_numpy import degrees_between
    import numpy as np
    import fitsio
    try:
        wcs, W, H, zoomscale, zoom,x,y = get_tile_wcs(zoom, x, y)
    except RuntimeError as e:
        return HttpResponse(e.strerror)
    rlo,d = wcs.pixelxy2radec(W, H/2)[-2:]
    rhi,d = wcs.pixelxy2radec(1, H/2)[-2:]
    r,d1 = wcs.pixelxy2radec(W/2, 1)[-2:]
    r,d2 = wcs.pixelxy2radec(W/2, H)[-2:]

    r,d = wcs.pixelxy2radec(W/2, H/2)[-2:]
    rad = max(degrees_between(r, d, rlo, d1),
              degrees_between(r, d, rhi, d2))

    if Tdepth is None:
        T = fits_table(os.path.join(basedir, 'decals-zpt-nondecals.fits'),
                            columns=['ccdra','ccddec','arawgain', 'avsky',
                                     'ccdzpt', 'filter', 'crpix1','crpix2',
                                     'crval1','crval2','cd1_1','cd1_2',
                                     'cd2_1','cd2_2', 'naxis1', 'naxis2', 'exptime', 'fwhm'])
        T.rename('ccdra',  'ra')
        T.rename('ccddec', 'dec')

        Tdepth = {}
        Tdepthkd = {}
        for b in ['g','r','z']:
            Tdepth[b] = T[T.filter == b]
            Tdepthkd[b] = tree_build_radec(Tdepth[b].ra, Tdepth[b].dec)

    T = Tdepth[band]
    Tkd = Tdepthkd[band]

    #I,J,d = match_radec(T.ra, T.dec, r, d, rad + 0.2)
    I = tree_search_radec(Tkd, r, d, rad + 0.2)
    print len(I), 'CCDs in range'
    if len(I) == 0:
        from django.http import HttpResponseRedirect
        return HttpResponseRedirect(settings.STATIC_URL + 'blank.jpg')

    depthiv = np.zeros((H,W), np.float32)
    for t in T[I]:
        twcs = Tan(*[float(x) for x in [
            t.crval1, t.crval2, t.crpix1, t.crpix2,
            t.cd1_1, t.cd1_2, t.cd2_1, t.cd2_2, t.naxis1, t.naxis2]])
        w,h = t.naxis1, t.naxis2
        r,d = twcs.pixelxy2radec([1,1,w,w], [1,h,h,1])
        ok,x,y = wcs.radec2pixelxy(r, d)
        #print 'x,y coords of CCD:', x, y
        x0 = int(x.min())
        x1 = int(x.max())
        y0 = int(y.min())
        y1 = int(y.max())
        if y1 < 0 or x1 < 0 or x0 >= W or y0 >= H:
            continue

        readnoise = 10. # e-; 7.0 to 15.0 according to DECam Data Handbook
        skysig = np.sqrt(t.avsky * t.arawgain + readnoise**2) / t.arawgain
        zpscale = 10.**((t.ccdzpt - 22.5)/2.5) * t.exptime
        sig1 = skysig / zpscale
        psf_sigma = t.fwhm / 2.35
        # point-source depth
        psfnorm = 1./(2. * np.sqrt(np.pi) * psf_sigma)
        detsig1 = sig1 / psfnorm

        #print '5-sigma point-source depth:', NanoMaggies.nanomaggiesToMag(detsig1 * 5.)

        div = 1 / detsig1**2
        depthiv[max(y0,0):min(y1,H), max(x0,0):min(x1,W)] += div

    ptsrc = -2.5 * (np.log10(np.sqrt(1./depthiv) * 5) - 9)
    ptsrc[depthiv == 0] = 0.

    if savecache:
        trymakedirs(tilefn)
    else:
        import tempfile
        f,tilefn = tempfile.mkstemp(suffix='.jpg')
        os.close(f)

    import pylab as plt
    plt.imsave(tilefn, ptsrc, vmin=22., vmax=25., cmap='hot')#nipy_spectral')

    return send_file(tilefn, 'image/jpeg', unlink=(not savecache))
Example #18
0
def map_sdss(req, ver, zoom, x, y, savecache=None, tag='sdss',
             get_images=False,
             ignoreCached=False,
             wcs=None,
             forcecache=False,
             forcescale=None,
             **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

    bands = 'gri'
    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]
            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))
Example #19
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))
Example #20
0
def find_alignments(fns, wcsfns, gaia_fn, aff_fn, aligned_fn):
    from astrometry.libkd.spherematch import tree_build_radec, trees_match
    from astrometry.libkd.spherematch import match_radec
    from astrometry.util.plotutils import plothist
    from astrometry.util.util import Tan
    import fitsio

    from astrom_common import getwcsoutline
    from singles import find_overlaps

    if True:
        WCS = []
        for fn in wcsfns:
            wcs = Tan(fn)
            WCS.append(wcs)

    names = [fn.replace('-bright.fits', '') for fn in fns]

    outlines = [getwcsoutline(wcs) for wcs in WCS]

    overlaps, areas = find_overlaps(outlines)

    print('Reading tables...')
    TT = [fits_table(fn) for fn in fns]
    print('Building trees...')
    kds = [tree_build_radec(T.ra, T.dec) for T in TT]

    for T, name in zip(TT, names):
        T.name = np.array([name] * len(T))

    allra = np.hstack([T.ra for T in TT])
    alldec = np.hstack([T.dec for T in TT])
    minra = np.min(allra)
    maxra = np.max(allra)
    mindec = np.min(alldec)
    maxdec = np.max(alldec)

    print('RA,Dec range:', minra, maxra, mindec, maxdec)

    plothist(allra, alldec)
    plt.axis([maxra, minra, mindec, maxdec])
    plt.xlabel('RA (deg)')
    plt.ylabel('Dec (deg)')
    plt.savefig('match-all.png')

    Tref = fits_table(gaia_fn)
    r_arcsec = 0.2
    I, J, d = match_radec(Tref.ra, Tref.dec, allra, alldec, r_arcsec / 3600.)
    dec = alldec[J]
    cosdec = np.cos(np.deg2rad(dec))
    dr = (Tref.ra[I] - allra[J]) * cosdec * 3600.
    dd = (Tref.dec[I] - alldec[J]) * 3600.
    plt.clf()
    rr = (-r_arcsec * 1000, +r_arcsec * 1000)
    plothist(dr * 1000., dd * 1000., nbins=100, range=(rr, rr))
    plt.xlabel('dRA (milli-arcsec)')
    plt.ylabel('dDec (milli-arcsec)')
    plt.savefig('match-all-ref-before.png')

    # Initial matching of all stars
    r_arcsec = 0.2
    I, J, d = match_radec(allra,
                          alldec,
                          allra,
                          alldec,
                          r_arcsec / 3600.,
                          notself=True)
    dec = alldec[I]
    cosdec = np.cos(np.deg2rad(dec))
    dr = (allra[I] - allra[J]) * cosdec * 3600.
    dd = (alldec[I] - alldec[J]) * 3600.

    plt.clf()
    rr = (-r_arcsec * 1000, +r_arcsec * 1000)
    plothist(dr * 1000., dd * 1000., nbins=100, range=(rr, rr))
    plt.xlabel('dRA (milli-arcsec)')
    plt.ylabel('dDec (milli-arcsec)')
    plt.savefig('match-all-before.png')

    hulls = []
    from scipy.spatial import ConvexHull
    for T in TT:
        hull = ConvexHull(np.vstack((T.ra, T.dec)).T)
        ra = T.ra[hull.vertices]
        ra = np.append(ra, ra[0])
        dec = T.dec[hull.vertices]
        dec = np.append(dec, dec[0])
        hulls.append((ra, dec))

    aligns = {}

    #for i in []:
    for i in range(len(kds)):
        for j in range(i + 1, len(kds)):
            print('Matching trees', i, 'and', j)

            r_arcsec = 0.2
            radius = np.deg2rad(r_arcsec / 3600)

            I, J, d2 = trees_match(kds[i], kds[j], radius)
            print(len(I), 'matches')
            if len(I) == 0:
                continue

            Ti = TT[i]
            Tj = TT[j]
            dec = Ti[I].dec
            cosdec = np.cos(np.deg2rad(dec))
            dr = (Ti[I].ra - Tj[J].ra) * cosdec * 3600.
            dd = (Ti[I].dec - Tj[J].dec) * 3600.

            if False:
                al = Alignment(Ti, Tj, searchradius=r_arcsec)
                print('Aligning...')
                if not al.shift():
                    print('Failed to find Alignment between fields')
                    continue
                aligns[(i, j)] = al

                plt.clf()
                plotalignment(al)
                plt.savefig('match-align-%02i-%02i.png' % (i, j))

            plt.clf()
            #plothist(np.append(Ti.ra, Tj.ra), np.append(Ti.dec, Tj.dec), docolorbar=False, doclf=False, dohot=False,
            #         imshowargs=dict(cmap=antigray))
            plothist(Ti.ra[I], Ti.dec[I], docolorbar=False, doclf=False)
            r, d = hulls[i]
            plt.plot(r, d, 'r-')
            r, d = hulls[j]
            plt.plot(r, d, 'b-')
            mra = Ti.ra[I]
            mdec = Ti.dec[I]
            mnra = np.min(mra)
            mxra = np.max(mra)
            mndec = np.min(mdec)
            mxdec = np.max(mdec)
            plt.plot([mnra, mnra, mxra, mxra, mnra],
                     [mndec, mxdec, mxdec, mndec, mndec], 'g-')

            plt.axis([maxra, minra, mindec, maxdec])
            plt.xlabel('RA (deg)')
            plt.ylabel('Dec (deg)')
            plt.savefig('match-radec-%02i-%02i.png' % (i, j))

            plt.clf()
            rr = (-r_arcsec, +r_arcsec)
            plothist(dr, dd, nbins=100, range=(rr, rr))
            plt.xlabel('dRA (arcsec)')
            plt.ylabel('dDec (arcsec)')
            plt.savefig('match-dradec-%02i-%02i.png' % (i, j))

    #for roundi,(Nk,R) in enumerate(NkeepRads):

    refrad = 0.15
    targetrad = 0.005

    ps = PlotSequence('shift')

    from astrom_intra import intrabrickshift
    from singles import plot_all_alignments

    #Rads = [0.25, 0.1]
    Rads = [0.2, 0.050, 0.020]
    #Rads = [0.1]
    affs = None
    # this is the reference point around which rotations take place, NOT reference catalog stars.
    refrd = None
    for roundi, R in enumerate(Rads):

        if roundi > 0:
            refrad = 0.050

        TT1 = TT

        nb = int(np.ceil(R / targetrad))
        nb = max(nb, 5)
        if nb % 2 == 0:
            nb += 1
        print('Round', roundi + 1, ': matching with radius', R)
        print('Nbins:', nb)

        # kwargs to pass to intrabrickshift
        ikwargs = {}
        minoverlap = 0.01
        tryoverlaps = (overlaps > minoverlap)
        ikwargs.update(
            do_affine=True,  #mp=mp,
            #alignplotargs=dict(bins=25),
            alignplotargs=dict(bins=50),
            overlaps=tryoverlaps)

        ikwargs.update(ref=Tref, refrad=refrad)

        # kwargs to pass to Alignment
        akwargs = {}

        i1 = intrabrickshift(TT1,
                             matchradius=R,
                             refradecs=refrd,
                             align_kwargs=dict(histbins=nb, **akwargs),
                             **ikwargs)

        refrd = i1.get_reference_radecs()

        filts = ['' for n in names]
        ap = i1.alplotgrid
        Nk = 100000
        plot_all_alignments(ap, R * 1000, refrad * 1000, roundi + 1, names,
                            filts, ps, overlaps, outlines, Nk)
        for T, aff in zip(TT, i1.affines):
            T.ra, T.dec = aff.apply(T.ra, T.dec)

        if affs is None:
            affs = i1.affines
        else:
            for a, a2 in zip(affs, i1.affines):
                a.add(a2)

    from astrom_common import Affine
    T = Affine.toTable(affs)
    T.filenames = fns
    #T.flt = fltfns
    #T.gst = gstfns
    #T.chip = chips

    # FAKE -- used as a name in alignment_plots
    T.gst = np.array([n + '.gst.fits' for n in names])

    T.writeto(aff_fn)

    # Final matching of all stars
    allra = np.hstack([T.ra for T in TT])
    alldec = np.hstack([T.dec for T in TT])

    r_arcsec = 0.2
    I, J, d = match_radec(allra,
                          alldec,
                          allra,
                          alldec,
                          r_arcsec / 3600.,
                          notself=True)
    dec = alldec[I]
    cosdec = np.cos(np.deg2rad(dec))
    dr = (allra[I] - allra[J]) * cosdec * 3600.
    dd = (alldec[I] - alldec[J]) * 3600.

    plt.clf()
    rr = (-r_arcsec * 1000, +r_arcsec * 1000)
    plothist(dr * 1000., dd * 1000., nbins=100, range=(rr, rr))
    plt.xlabel('dRA (milli-arcsec)')
    plt.ylabel('dDec (milli-arcsec)')
    plt.savefig('match-all-after.png')

    I, J, d = match_radec(Tref.ra, Tref.dec, allra, alldec, r_arcsec / 3600.)
    dec = alldec[J]
    cosdec = np.cos(np.deg2rad(dec))
    dr = (Tref.ra[I] - allra[J]) * cosdec * 3600.
    dd = (Tref.dec[I] - alldec[J]) * 3600.
    plt.clf()
    rr = (-r_arcsec * 1000, +r_arcsec * 1000)
    plothist(dr * 1000., dd * 1000., nbins=100, range=(rr, rr))
    plt.xlabel('dRA (milli-arcsec)')
    plt.ylabel('dDec (milli-arcsec)')
    plt.savefig('match-all-ref-after.png')

    r_arcsec = 0.02
    I, J, d = match_radec(allra,
                          alldec,
                          allra,
                          alldec,
                          r_arcsec / 3600.,
                          notself=True)
    dec = alldec[I]
    cosdec = np.cos(np.deg2rad(dec))
    dr = (allra[I] - allra[J]) * cosdec * 3600.
    dd = (alldec[I] - alldec[J]) * 3600.
    plt.clf()
    rr = (-r_arcsec * 1000, +r_arcsec * 1000)
    plothist(dr * 1000., dd * 1000., nbins=100, range=(rr, rr))
    plt.xlabel('dRA (milli-arcsec)')
    plt.ylabel('dDec (milli-arcsec)')
    plt.savefig('match-all-after2.png')

    T = fits_table()
    T.ra = allra
    T.dec = alldec
    for col in [
            'f814w_vega', 'f475w_vega', 'f336w_vega', 'f275w_vega',
            'f110w_vega', 'f160w_vega', 'name'
    ]:
        T.set(col, np.hstack([t.get(col) for t in TT]))
    T.writeto(aligned_fn)

    if False:
        from singles import alignment_plots

        dataset = 'M31'
        Nkeep = 100000
        R = 0.1
        minoverlap = 0.01
        perfield = False
        nocache = True

        from astrometry.util.multiproc import multiproc
        mp = multiproc()

        filts = ['F475W' for n in names]
        chips = [-1] * len(names)
        exptimes = [1] * len(names)
        Nall = [0] * len(names)
        rd = (minra, maxra, mindec, maxdec)
        cnames = names
        meta = (chips, names, cnames, filts, exptimes, Nall, rd)

        alignment_plots(afffn,
                        dataset,
                        Nkeep,
                        0,
                        R,
                        minoverlap,
                        perfield,
                        nocache,
                        mp,
                        0,
                        tables=(TT, outlines, meta),
                        lexsort=False)
Example #21
0
def main():
    os.environ['DESIMODEL'] = '/global/homes/d/dstn/desimodel-data'

    global hw
    global stuck_x
    global stuck_y
    global stuck_loc
    global starkd

    hw = load_hardware()

    # From fiberassign/stucksky.py: find X,Y positions of stuck positioners.

    # (grab the hw dictionaries once -- these are python wrappers over C++ so not simple accessors)
    state = hw.state
    devtype = hw.loc_device_type
    stuck_loc = [
        loc for loc in hw.locations
        if (((state[loc] & (FIBER_STATE_STUCK | FIBER_STATE_BROKEN)
              ) == FIBER_STATE_STUCK) and (devtype[loc] == 'POS'))
    ]
    print(len(stuck_loc), 'stuck positioners')
    theta_pos = hw.loc_theta_pos
    theta_off = hw.loc_theta_offset
    phi_pos = hw.loc_phi_pos
    phi_off = hw.loc_phi_offset
    stuck_theta = [theta_pos[loc] + theta_off[loc] for loc in stuck_loc]
    stuck_phi = [phi_pos[loc] + phi_off[loc] for loc in stuck_loc]
    curved_mm = hw.loc_pos_curved_mm
    theta_arm = hw.loc_theta_arm
    phi_arm = hw.loc_phi_arm
    theta_min = hw.loc_theta_min
    theta_max = hw.loc_theta_max
    phi_min = hw.loc_phi_min
    phi_max = hw.loc_phi_max
    # Convert positioner angle orientations to curved focal surface X / Y (not CS5)
    # Note:  we could add some methods to the python bindings to vectorize this or make it less clunky...
    stuck_x = np.zeros(len(stuck_loc))
    stuck_y = np.zeros(len(stuck_loc))
    for iloc, (loc, theta,
               phi) in enumerate(zip(stuck_loc, stuck_theta, stuck_phi)):
        loc_x, loc_y = hw.thetaphi_to_xy(curved_mm[loc], theta, phi,
                                         theta_arm[loc], phi_arm[loc],
                                         theta_off[loc], phi_off[loc],
                                         theta_min[loc], phi_min[loc],
                                         theta_max[loc], phi_max[loc], True)
        stuck_x[iloc] = loc_x
        stuck_y[iloc] = loc_y

    tiles = Table.read(
        '/global/cfs/cdirs/desi/target/surveyops/ops/tiles-main.ecsv')
    print(len(tiles), 'tiles')
    # Deduplicate tiles with same RA,Dec center
    tilera = tiles['RA']
    tiledec = tiles['DEC']
    tileid = tiles['TILEID']
    rdtile = {}
    tilemap = {}
    for tid, r, d in zip(tileid, tilera, tiledec):
        key = r, d
        if key in rdtile:
            # already seen a tile with this RA,Dec; point to it
            tilemap[tid] = rdtile[key]
        else:
            rdtile[key] = tid
    del rdtile

    tnow = datetime.now()
    tile_obstime = tnow.isoformat(timespec='seconds')
    mjd = Time(tnow).mjd

    stars = fits_table(
        '/global/cfs/cdirs/cosmo/data/legacysurvey/dr9/masking/gaia-mask-dr9.fits.gz'
    )
    print(len(stars), 'stars for masking')

    print('Moving to MJD', mjd)
    ra, dec = radec_at_mjd(stars.ra, stars.dec, stars.ref_epoch.astype(float),
                           stars.pmra, stars.pmdec, stars.parallax, mjd)
    assert (np.all(np.isfinite(ra)))
    assert (np.all(np.isfinite(dec)))
    stars.ra = ra
    stars.dec = dec
    print('Building kd-tree...')

    starkd = tree_build_radec(stars.ra, stars.dec)

    match_radius = deg2dist(30. / 3600.)

    stuck_loc = np.array(stuck_loc)

    allresults = {}

    mp = multiproc(32)

    print('Building arg lists...')
    args = []
    for tid, tile_ra, tile_dec, tile_obsha in zip(tileid, tilera, tiledec,
                                                  tiles['DESIGNHA']):
        # skip duplicate tiles
        if tid in tilemap:
            continue
        # "fieldrot"
        tile_theta = field_rotation_angle(tile_ra, tile_dec, mjd)
        args.append((tid, tile_ra, tile_dec, tile_obstime, tile_theta,
                     tile_obsha, match_radius))

    print('Matching', len(args), 'unique tile RA,Decs in parallel...')
    res = mp.map(_match_tile, args)

    print('Organizing results...')
    T = fits_table()
    T.tileid = []
    T.loc = []
    T.petal = []
    T.device = []
    T.fiber = []
    T.pos_ra = []
    T.pos_dec = []
    T.star_ra = []
    T.star_dec = []
    T.dist_arcsec = []
    T.mask_mag = []

    loc_to_petal = hw.loc_petal
    loc_to_device = hw.loc_device
    loc_to_fiber = hw.loc_fiber

    for vals in res:
        if vals is None:
            continue
        tileid, I, pos_ra, pos_dec, pos_loc, dists = vals
        T.tileid.extend([tileid] * len(I))
        T.loc.extend(pos_loc)
        for loc in pos_loc:
            T.petal.append(loc_to_petal[loc])
            T.device.append(loc_to_device[loc])
            T.fiber.append(loc_to_fiber[loc])
        T.pos_ra.extend(pos_ra)
        T.pos_dec.extend(pos_dec)
        T.star_ra.extend(stars.ra[I])
        T.star_dec.extend(stars.dec[I])
        T.dist_arcsec.extend(dists)
        T.mask_mag.extend(stars.mask_mag[I])
    T.to_np_arrays()
    T.writeto('stuck-on-stars.fits')