Example #1
0
def skyplot():
    plot = Plotstuff(size=(800, 800), rdw=(103.1, 37.45, 0.8), outformat='png')
    plot.color = 'verydarkblue'
    plot.plot('fill')

    for ext in range(1, 17):
        fn = 'mos3.68488.fits'
        hdr = fitsio.read_header(fn, ext=ext)
        wcs = wcs_pv2sip_hdr(hdr)
        plot.color = 'red'
        plot.outline.wcs = anwcs_new_sip(wcs)
        plot.plot('outline')

        plot.color = 'white'
        plot.apply_settings()
        rc, dc = wcs.radec_center()
        plot.text_radec(rc, dc, hdr['EXTNAME'])

    plot.color = 'white'
    for ext in range(1, 17):
        fn = 'an2/mos3.68488.ext%02i.wcs' % ext
        plot.outline.wcs = anwcs(fn)
        plot.plot('outline')

    plot.rgb = (0.2, 0.2, 0.2)
    plot.plot_grid(0.1, 0.1)
    plot.color = 'gray'
    plot.plot_grid(0.5, 0.5, 0.5, 0.5)
    plot.write('plot.png')
Example #2
0
 def get_wcs(self, hdr):
     # Older images have ZPX, newer TPV.
     if hdr['CTYPE1'] == 'RA---TPV':
         from astrometry.util.util import wcs_pv2sip_hdr
         wcs = wcs_pv2sip_hdr(hdr)
     else:
         from astrometry.util.util import Tan
         hdr['CTYPE1'] = 'RA---TAN'
         hdr['CTYPE2'] = 'DEC--TAN'
         wcs = Tan(hdr)
     return wcs
Example #3
0
    def get_wcs(self):
        hdr = fitsio.read_header(self.imgfn, self.hdu)
        wcs = wcs_pv2sip_hdr(hdr)

        phdr = fitsio.read_header(self.imgfn, 0)

        dra, ddec = self.decals.get_astrometric_zeropoint_for(self)
        r, d = wcs.get_crval()
        print('Applying astrometric zeropoint:', (dra, ddec))
        wcs.set_crval((r + dra, d + ddec))

        wcs.version = ''
        wcs.plver = phdr.get('PLVER', '').strip()

        return wcs
Example #4
0
    def get_wcs(self):
        hdr = fitsio.read_header(self.imgfn, self.hdu)
        wcs = wcs_pv2sip_hdr(hdr)

        phdr = fitsio.read_header(self.imgfn, 0)

        dra,ddec = self.decals.get_astrometric_zeropoint_for(self)
        r,d = wcs.get_crval()
        print('Applying astrometric zeropoint:', (dra,ddec))
        wcs.set_crval((r + dra, d + ddec))

        wcs.version = ''
        wcs.plver = phdr.get('PLVER', '').strip()
        
        return wcs
Example #5
0
def get_wcs(hdr, tpv_to_sip=True):
    # Thanks Dstn :)
    # https://github.com/legacysurvey/legacypipe/blob/master/py/legacypipe/cpimage.py#102
    width = hdr['NAXIS1']
    height = hdr['NAXIS2']
    if not (tpv_to_sip):
        # extract wcs from fits header directly
        wcs= Tan(hdr['CRVAL1'], hdr['CRVAL2'],hdr['CRPIX1'],hdr['CRPIX2'],\
                 hdr['CD1_1'],hdr['CD1_2'],hdr['CD2_1'],hdr['CD2_2'],\
                 float(width),float(height))
    else:
        # Make sure the PV-to-SIP converter samples enough points for small
        # images
        stepsize = 0
        if min(width, height) < 600:
            stepsize = min(width, height) / 10.
        wcs = wcs_pv2sip_hdr(hdr, stepsize=stepsize)
    # Dstn adds an offset correction i.e.
    # Correction: ccd,ccdraoff, decoff from zeropoints file
    # Should I do this?
    return wcs
Example #6
0
 def get_wcs(self):
     # Make sure the PV-to-SIP converter samples enough points for small
     # images
     stepsize = 0
     if min(self.width, self.height) < 600:
         stepsize = min(self.width, self.height) / 10.;
     hdr = self.read_image_header()
     if self.camera == '90prime':
         # WCS is in myriad of formats
         # Don't support TNX yet, use TAN for now
         hdr = self.read_image_header()
         hdr['CTYPE1'] = 'RA---TAN'
         hdr['CTYPE2'] = 'DEC--TAN'
     wcs = wcs_pv2sip_hdr(hdr, stepsize=stepsize)
     # Correctoin: ccd,ccdraoff, decoff from zeropoints file
     dra,ddec = self.dradec
     print('Applying astrometric zeropoint:', (dra,ddec))
     r,d = wcs.get_crval()
     wcs.set_crval((r + dra, d + ddec))
     wcs.version = ''
     phdr = self.read_image_primary_header()
     wcs.plver = phdr.get('PLVER', '').strip()
     return wcs
Example #7
0
 def get_wcs(self,hdr=None):
     # Make sure the PV-to-SIP converter samples enough points for small
     # images
     stepsize = 0
     if min(self.width, self.height) < 600:
         stepsize = min(self.width, self.height) / 10.;
     if hdr is None:
         hdr = self.read_image_header()
     #if self.camera == '90prime':
         # WCS is in myriad of formats
         # Don't support TNX yet, use TAN for now
     #    hdr = self.read_image_header()
     #    hdr['CTYPE1'] = 'RA---TAN'
     #    hdr['CTYPE2'] = 'DEC--TAN'
     wcs = wcs_pv2sip_hdr(hdr, stepsize=stepsize)
     # Correctoin: ccd,ccdraoff, decoff from zeropoints file
     dra,ddec = self.dradec
     print('Applying astrometric zeropoint:', (dra,ddec))
     r,d = wcs.get_crval()
     wcs.set_crval((r + dra, d + ddec))
     wcs.version = ''
     phdr = self.read_image_primary_header()
     wcs.plver = phdr.get('PLVER', '').strip()
     return wcs
Example #8
0
                      3.)
Tnear = T[J]
print('Found', len(Tnear), 'tiles nearby')
# sort by distance from center
I = np.argsort(d)
Tnear.cut(I)
Tnear.rename('pass', 'passnum')

# MzLS_594295_z

ps = PlotSequence('tile', format='%03i')

wcses = []
for ext in range(1, 4 + 1):
    hdr = fitsio.read_header(fn, ext=ext)
    wcs = wcs_pv2sip_hdr(hdr)
    wcses.append(wcs)
    print('WCS', wcs)

PW, PH = 800, 800
plot = Plotstuff(size=(PW, PH), rdw=(tile.ra, tile.dec, 2), outformat='png')
plot.color = 'verydarkblue'
plot.plot('fill')

plot.color = 'white'
plot.alpha = 0.25
plot.outline.fill = True
plot.apply_settings()

for passnum in [1, 2, 3]:
Example #9
0
def main():
    # Where are the data?
    datadir = os.path.join(os.path.dirname(__file__), 'data-decam')
    name = 'decam-520206-S16'
    imagefn = os.path.join(datadir, '%s-image-sub.fits' % name)
    invvarfn = os.path.join(datadir, '%s-invvar-sub.fits' % name)
    psfexfn = os.path.join(datadir, '%s-psfex.fits' % name)
    catfn = os.path.join(datadir, 'tractor-1816p325-sub.fits')

    # Read the image and inverse-variance maps.
    image = fitsio.read(imagefn)
    invvar = fitsio.read(invvarfn)
    # The DECam inverse-variance maps are unfortunately corrupted
    # by fpack, causing zeros to become negative.  Fix those.
    invvar[invvar < np.median(invvar) * 0.1] = 0.
    H, W = image.shape
    print('Subimage size:', image.shape)

    # For the PSF model, we need to know what subimage region this is:
    subimage_offset = (35, 1465)
    # We also need the calibrated zeropoint.
    zeropoint = 24.7787

    # What filter was this image taken in?  (z)
    prim_header = fitsio.read_header(imagefn)
    band = prim_header['FILTER'].strip()[0]
    print('Band:', band)
    # These DECam images were calibrated so that the zeropoints need
    # an exposure-time factor, so add that in.
    exptime = prim_header['EXPTIME']
    zeropoint += 2.5 * np.log10(exptime)

    # Read the PsfEx model file
    psf = PixelizedPsfEx(psfexfn)
    # Instantiate a constant pixelized PSF at the image center
    # (of the subimage)
    x0, y0 = subimage_offset
    psf = psf.constantPsfAt(x0 + W / 2., y0 + H / 2.)

    # Load the WCS model from the header
    # We convert from the RA---TPV type to RA---SIP
    header = fitsio.read_header(imagefn, ext=1)
    wcsobj = wcs_pv2sip_hdr(header, stepsize=10)

    # We'll just use a rough sky estimate...
    skyval = np.median(image)

    # Create the Tractor Image (tim).
    tim = Image(data=image,
                invvar=invvar,
                psf=psf,
                wcs=ConstantFitsWcs(wcsobj),
                sky=ConstantSky(skyval),
                photocal=LinearPhotoCal(
                    NanoMaggies.zeropointToScale(zeropoint), band=band))

    # Read the official DECaLS DR3 catalog -- it has only two sources in this subimage.
    catalog = fits_table(catfn)
    print('Read', len(catalog), 'sources')
    print('Source types:', catalog.type)

    # Create Tractor sources corresponding to these two catalog
    # entries.

    # In DECaLS, the "SIMP" type is a round Exponential galaxy with a
    # fixed 0.45" radius, but we'll treat it as a general Exp galaxy.

    sources = []
    for c in catalog:
        # Create a "position" object given the catalog RA,Dec
        position = RaDecPos(c.ra, c.dec)
        # Create a "brightness" object; in the catalog, the fluxes are
        # stored in a [ugrizY] array, so pull out the right index
        band_index = 'ugrizY'.index(band)
        flux = c.decam_flux[band_index]
        brightness = NanoMaggies(**{band: flux})

        # Depending on the source classification in the catalog, pull
        # out different fields for the galaxy shape, and for the
        # galaxy type.  The DECaLS catalogs, conveniently, store
        # galaxy shapes as (radius, e1, e2) ellipses.
        if c.type.strip() == 'DEV':
            shape = EllipseE(c.shapedev_r, c.shapedev_e1, c.shapedev_e2)
            galclass = DevGalaxy
        elif c.type.strip() == 'SIMP':
            shape = EllipseE(c.shapeexp_r, c.shapeexp_e1, c.shapeexp_e2)
            galclass = ExpGalaxy
        else:
            assert (False)
        # Create the tractor galaxy object
        source = galclass(position, brightness, shape)
        print('Created', source)
        sources.append(source)

    # Create the Tractor object -- a list of tractor Images and a list of tractor sources.
    tractor = Tractor([tim], sources)

    # Render the initial model image.
    print('Getting initial model...')
    mod = tractor.getModelImage(0)
    make_plot(tim, mod, 'Initial Scene', 'mod0.png')

    # Instantiate a new source at the location of the unmodelled peak.
    print('Adding new source...')
    # Find the peak very naively...
    ipeak = np.argmax((image - mod) * tim.inverr)
    iy, ix = np.unravel_index(ipeak, tim.shape)
    print('Residual peak at', ix, iy)
    # Compute the RA,Dec location of the peak...
    radec = tim.getWcs().pixelToPosition(ix, iy)
    print('RA,Dec', radec)

    # Try modelling it as a point source.
    # We'll initialize the brightness arbitrarily to 1 nanomaggy (= mag 22.5)
    brightness = NanoMaggies(**{band: 1.})
    source = PointSource(radec, brightness)

    # Add it to the catalog!
    tractor.catalog.append(source)

    # Render the new model image with this source added.
    mod = tractor.getModelImage(0)
    make_plot(tim, mod, 'New Source (Before Fit)', 'mod1.png')

    print('Fitting new source...')
    # Now we're going to fit for the properties of the new source we
    # added.
    # We don't want to fit for any of the image calibration properties:
    tractor.freezeParam('images')
    # And we don't (yet) want to fit the existing sources.  The new
    # source is index number 2, so freeze everything else in the catalog.
    tractor.catalog.freezeAllBut(2)

    print('Fitting parameters:')
    tractor.printThawedParams()

    # Do the actual optimization:
    tractor.optimize_loop()

    mod = tractor.getModelImage(0)
    make_plot(tim, mod, 'New Source Fit', 'mod2.png')

    print('Fitting sources simultaneously...')
    # Now let's unfreeze all the sources and fit them simultaneously.
    tractor.catalog.thawAllParams()
    tractor.printThawedParams()

    tractor.optimize_loop()

    mod = tractor.getModelImage(0)
    make_plot(tim, mod, 'Simultaneous Fit', 'mod3.png')
Example #10
0
def mosaic():
    '''
    > cp ~/cosmo/staging/mosaicz/MZLS_CP/CP20180102/k4m_180103_040423_ooi_zd_v1.fits.fz /tmp
    > funpack /tmp/k4m_180103_040423_ooi_zd_v1.fits.fz
    > fitsgetext -i /tmp/k4m_180103_040423_ooi_zd_v1.fits -o mosaic-%02i.wcs -a -H
    > cat mosaic-??.wcs > mosaic.wcs
    > for ((i=1; i<=4; i++)); do modhead mosaic.wcs+$i NAXIS2; modhead mosaic.wcs+$i NAXIS2 0; done
    NAXIS2  =                 4079 / Axis length

    NAXIS2  =                 4079 / Axis length

    NAXIS2  =                 4079 / Axis length

    NAXIS2  =                 4061 / Axis length
    '''

    plt.figure(figsize=(4, 3))
    plt.subplots_adjust(left=0.15, right=0.99, top=0.99, bottom=0.15)

    T = fits_table('obstatus/mosaic-tiles_obstatus.fits')
    print(len(T), 'tiles')
    T.rename('pass', 'passnum')
    T.cut(T.passnum <= 3)
    print(len(T), 'tiles with passnum <= 3')
    ra, dec = 180.216, 40.191
    #ra,dec = 180., 40.
    I, J, d = match_radec(T.ra, T.dec, ra, dec, 2.)
    print(len(I), 'tiles near', ra, dec)
    T.cut(I)
    T.dist = d
    print('dists:', d)
    print('Passes:', T.passnum)

    F = fitsio.FITS(os.path.join(os.path.dirname(__file__), 'mosaic.wcs'))
    wcs = []

    heights = [4079, 4079, 4079, 4061]

    for i in range(1, len(F)):
        hdr = F[i].read_header()
        W = hdr['NAXIS1']
        wcs.append(wcs_pv2sip_hdr(hdr, H=heights[i - 1], W=W))
        print('WCS:', wcs[-1])

    # Rendering canvas
    W, H = 2200, 2200
    pixsc = 4. / 3600.
    targetwcs = Tan(ra, dec, W / 2. + 0.5, H / 2. + 0.5, -pixsc, 0., 0., pixsc,
                    float(W), float(H))
    II = np.lexsort((T.dist, T.passnum))

    print('First tile center:', T.ra[II[0]], T.dec[II[0]])

    # This is for making the (vector) PDF format tiling images.
    for maxit in [0, 8, 36, 37, 44, 73, 74, 82, 112]:
        plot = Plotstuff(outformat='pdf',
                         ra=ra,
                         dec=dec,
                         width=W * pixsc,
                         size=(W, H),
                         outfn='tile-mosaic-%02i.pdf' % maxit)
        plot.color = 'white'
        plot.alpha = 1.
        plot.plot('fill')

        out = plot.outline
        out.fill = True
        out.stepsize = 1024.
        plot.color = 'black'
        plot.alpha = 0.4
        plot.apply_settings()

        for it, t in enumerate(T[II]):
            print('Tile', it, 'pass', t.passnum)
            for w in wcs:
                w.set_crval((t.ra, t.dec))
                out.wcs = anwcs_new_sip(w)
                plot.plot('outline')
            if it == maxit:
                print('Writing', it)
                plot.write()
                break

    # # And this is for PNG-format tiling images and histograms.
    cov = np.zeros((H, W), np.uint8)
    for it, t in enumerate(T[II]):
        print('Tile', it, 'pass', t.passnum)
        for w in wcs:
            w.set_crval((t.ra, t.dec))
            try:
                Yo, Xo, Yi, Xi, nil = resample_with_wcs(targetwcs, w)
            except:
                continue
            cov[Yo, Xo] += 1

        if it in [0, 8, 36, 37, 44, 73, 74, 82, 112]:
            mx = {1: 2, 2: 4, 3: 6}[t.passnum]
            # plt.clf()
            # plt.imshow(cov, interpolation='nearest', origin='lower', vmin=0, vmax=mx)
            # plt.colorbar()
            # plt.savefig('tile-%02i.png' % it)
            plt.imsave('tile-mosaic-%02i.png' % it,
                       cov,
                       origin='lower',
                       vmin=0,
                       vmax=mx,
                       cmap=antigray)

        if it in [36, 73, 112]:
            from collections import Counter
            print('Coverage counts:', Counter(cov.ravel()).most_common())
            bins = -0.5 + np.arange(8)
            plt.clf()
            n, b, p = plt.hist(cov.ravel(), bins=bins, normed=True)
            #plt.hist(cov.ravel(), bins=bins, normed=True, cumulative=True, histtype='step')
            # Cumulative histogram from the right...
            xx, yy = [], []
            for blo, bhi, ni in reversed(list(zip(bins, bins[1:], n))):
                nc = float(np.sum(cov.ravel() > blo)) / len(cov.ravel())
                yy.extend([nc, nc])
                xx.extend([bhi, blo])
                if ni > 0:
                    if nc != ni:
                        if nc > ni + 0.03:
                            # If there's room, label the histogram bin above, else below
                            plt.text((blo + bhi) / 2.,
                                     ni,
                                     '%.1f \%%' % (100. * ni),
                                     ha='center',
                                     va='bottom',
                                     color='k')
                        else:
                            plt.text((blo + bhi) / 2.,
                                     ni - 0.01,
                                     '%.1f \%%' % (100. * ni),
                                     ha='center',
                                     va='top',
                                     color='k')
                    plt.text((blo + bhi) / 2.,
                             nc,
                             '%.1f \%%' % (100. * nc),
                             ha='center',
                             va='bottom',
                             color='k')

            plt.plot(xx, yy, 'k-')

            plt.xlim(bins.min(), bins.max())
            plt.ylim(0., 1.1)
            plt.xlabel('Number of exposures')
            plt.ylabel('Fraction of sky')
            plt.savefig('hist-mosaic-%02i.pdf' % it)
Example #11
0
def decam():
    '''
    cp ~/cosmo/staging/decam/DECam_CP/CP20170731/c4d_170801_080516_oki_g_v1.fits.fz /tmp
    funpack /tmp/c4d_170801_080516_oki_g_v1.fits.fz
    fitsgetext -i /tmp/c4d_170801_080516_oki_g_v1.fits -o decam-%02i.wcs -a -H
    cat decam-??.wcs > decam.wcs
    for ((i=1; i<=61; i++)); do modhead decam.wcs+$i NAXIS2 0; done
    '''

    plt.figure(figsize=(4, 3))
    plt.subplots_adjust(left=0.15, right=0.99, top=0.99, bottom=0.15)

    T = fits_table('obstatus/decam-tiles_obstatus.fits')
    T.rename('pass', 'passnum')
    ra, dec = 0.933, 0.
    I, J, d = match_radec(T.ra, T.dec, ra, dec, 5.)  #2.8)
    print(len(I), 'tiles near 0,0')
    T.cut(I)
    T.dist = d
    print('dists:', d)
    print('Passes:', T.passnum)

    F = fitsio.FITS(os.path.join(os.path.dirname(__file__), 'decam.wcs'))
    wcs = []
    for i in range(1, len(F)):
        hdr = F[i].read_header()
        wcs.append(wcs_pv2sip_hdr(hdr, W=2046, H=4094))

    W, H = 5000, 5000
    pixsc = 4. / 3600.
    targetwcs = Tan(ra, dec, W / 2. + 0.5, H / 2. + 0.5, -pixsc, 0., 0., pixsc,
                    float(W), float(H))
    II = np.lexsort((T.dist, T.passnum))

    # This is for making the (vector) PDF format tiling images.
    for maxit in [0, 6, 30, 31, 37, 61, 62, 68, 90]:
        #mx = { 1: 2, 2: 4, 3: 6 }[t.passnum]
        plot = Plotstuff(outformat='pdf',
                         ra=ra,
                         dec=dec,
                         width=W * pixsc,
                         size=(W, H),
                         outfn='tile-%02i.pdf' % maxit)
        plot.color = 'white'
        plot.alpha = 1.
        plot.plot('fill')

        out = plot.outline
        out.fill = True
        out.stepsize = 1024.
        plot.color = 'black'
        plot.alpha = 0.4
        plot.apply_settings()

        for it, t in enumerate(T[II]):
            print('Tile', it, 'pass', t.passnum)
            for w in wcs:
                w.set_crval((t.ra, t.dec))
                out.wcs = anwcs_new_sip(w)
                plot.plot('outline')
            if it == maxit:
                print('Writing', it)
                plot.write()
                break

    # And this is for PNG-format tiling images and histograms.
    cov = np.zeros((H, W), np.uint8)
    for it, t in enumerate(T[II]):
        print('Tile', it, 'pass', t.passnum)
        for w in wcs:
            w.set_crval((t.ra, t.dec))
            #print('WCS:', w)
            try:
                Yo, Xo, Yi, Xi, nil = resample_with_wcs(targetwcs, w)
            except:
                #import traceback
                #traceback.print_exc()
                continue
            cov[Yo, Xo] += 1

        if it in [0, 6, 30, 31, 37, 61, 62, 68, 90]:
            mx = {1: 2, 2: 4, 3: 6}[t.passnum]
            # plt.clf()
            # plt.imshow(cov, interpolation='nearest', origin='lower', vmin=0, vmax=mx)
            # plt.colorbar()
            # plt.savefig('tile-%02i.png' % it)

            plt.imsave('tile-%02i.png' % it,
                       cov,
                       origin='lower',
                       vmin=0,
                       vmax=mx,
                       cmap=antigray)
            #plt.imsave('tile-%02i.pdf' % it, cov, origin='lower', vmin=0, vmax=mx, cmap=antigray, format='pdf')

        if it in [30, 61, 90]:
            from collections import Counter
            print('Coverage counts:', Counter(cov.ravel()).most_common())
            bins = -0.5 + np.arange(8)
            plt.clf()
            n, b, p = plt.hist(cov.ravel(), bins=bins, normed=True)
            #plt.hist(cov.ravel(), bins=bins, normed=True, cumulative=True, histtype='step')
            # Cumulative histogram from the right...
            xx, yy = [], []
            for blo, bhi, ni in reversed(zip(bins, bins[1:], n)):
                nc = float(np.sum(cov.ravel() > blo)) / len(cov.ravel())
                yy.extend([nc, nc])
                xx.extend([bhi, blo])
                if ni > 0:
                    if nc != ni:
                        if nc > ni + 0.03:
                            # If there's room, label the histogram bin above, else below
                            plt.text((blo + bhi) / 2.,
                                     ni,
                                     '%.1f \%%' % (100. * ni),
                                     ha='center',
                                     va='bottom',
                                     color='k')
                        else:
                            plt.text((blo + bhi) / 2.,
                                     ni - 0.01,
                                     '%.1f \%%' % (100. * ni),
                                     ha='center',
                                     va='top',
                                     color='k')
                    plt.text((blo + bhi) / 2.,
                             nc,
                             '%.1f \%%' % (100. * nc),
                             ha='center',
                             va='bottom',
                             color='k')

            plt.plot(xx, yy, 'k-')

            plt.xlim(bins.min(), bins.max())
            plt.ylim(0., 1.1)
            plt.xlabel('Number of exposures')
            plt.ylabel('Fraction of sky')
            #plt.title('DECaLS tiling, %i pass%s' % (t.passnum, t.passnum > 1 and 'es' or ''))
            #plt.savefig('hist-%02i.png' % it)
            plt.savefig('hist-%02i.pdf' % it)
Example #12
0
    img,imghdr = fitsio.read(imgfn, ext=ext, header=True)
    print('Read image', img.shape, img.dtype)
    img = img.astype(np.float32)
    H,W = img.shape
    
    band = imghdr['FILTER'][0]
    print('Band:', band)
    photocal = CfhtLinearPhotoCal(imghdr, band)
    
    headers = parse_head_file(headfn)
    print('Read headers:', len(headers))
    
    wcshdr = headers[ext-1]
    wcshdr['IMAGEW'] = W
    wcshdr['IMAGEH'] = H
    wcs = wcs_pv2sip_hdr(wcshdr)
    print('WCS pixel scale:', wcs.pixel_scale())
    
    ok,xx,yy = wcs.radec2pixelxy(cat.ra, cat.dec)
    print('Ext', ext, 'x range', int(xx.min()), int(xx.max()), 'y range', int(yy.min()), int(yy.max()))

    cat.xx = xx
    cat.yy = yy
    
    # # Estimate per-pixel noise via Blanton's 5-pixel MAD
    slice1 = (slice(0,-5,10),slice(0,-5,10))
    slice2 = (slice(5,None,10),slice(5,None,10))
    mad = np.median(np.abs(img[slice1] - img[slice2]).ravel())
    sig1 = 1.4826 * mad / np.sqrt(2.)
    print('sig1 estimate:', sig1)
    inverr = np.ones_like(img) / sig1
Example #13
0
 def get_wcs(self, hdr):
     from astrometry.util.util import wcs_pv2sip_hdr
     # HACK -- convert TPV WCS header to SIP.
     wcs = wcs_pv2sip_hdr(hdr)
     #print('Converted WCS to', wcs)
     return wcs
Example #14
0
    img, imghdr = fitsio.read(imgfn, ext=ext, header=True)
    print('Read image', img.shape, img.dtype)
    img = img.astype(np.float32)
    H, W = img.shape

    band = imghdr['FILTER'][0]
    print('Band:', band)
    photocal = CfhtLinearPhotoCal(imghdr, band)

    headers = parse_head_file(headfn)
    print('Read headers:', len(headers))

    wcshdr = headers[ext - 1]
    wcshdr['IMAGEW'] = W
    wcshdr['IMAGEH'] = H
    wcs = wcs_pv2sip_hdr(wcshdr)
    print('WCS pixel scale:', wcs.pixel_scale())

    ok, xx, yy = wcs.radec2pixelxy(cat.ra, cat.dec)
    print('Ext', ext, 'x range', int(xx.min()), int(xx.max()), 'y range',
          int(yy.min()), int(yy.max()))

    cat.xx = xx
    cat.yy = yy

    # # Estimate per-pixel noise via Blanton's 5-pixel MAD
    slice1 = (slice(0, -5, 10), slice(0, -5, 10))
    slice2 = (slice(5, None, 10), slice(5, None, 10))
    mad = np.median(np.abs(img[slice1] - img[slice2]).ravel())
    sig1 = 1.4826 * mad / np.sqrt(2.)
    print('sig1 estimate:', sig1)
Example #15
0
def main(passnum, threads):

    global udecs
    global P3
    global T
    global tilewcs
    global exps
    global bad_expids
    global tileid_to_depth

    ps = PlotSequence('covfill-p%i' % passnum)

    retirablefn = 'retirable-p%i.fits' % passnum
    depthsfn = 'all-depths-p%i.fits' % passnum

    if os.path.exists(retirablefn):
        R = fits_table(retirablefn)
        pcts = np.arange(0, 101)
        target = 22.5
        req_pcts = [0, 2, 2, 5, 5, 10, 10, 100]
        req_depths = [0, 0, target-0.6, target-0.6,
                      target-0.3, target-0.3, target, target]

        maglo, maghi = 21,23

        plt.clf()
        for depths in R.depths:
            plt.plot(pcts, np.clip(depths, maglo, maghi), 'b-',
                     alpha=0.1)
        plt.plot(req_pcts, np.clip(req_depths, maglo, maghi), 'k-',
                 lw=2, alpha=0.5)
        plt.ylim(maglo, maghi)
        plt.xlim(0, 100)
        plt.xlabel('Coverage fraction')
        plt.ylabel('Existing depth')
        plt.suptitle('MzLS: retirable pass-%i tiles: %i' % (passnum,len(R)))
        ps.savefig()

        # Where are they on the sky?
        T = fits_table('obstatus/mosaic-tiles_obstatus.fits')

        T.cut(T.in_desi == 1)
        T.cut(T.get('pass') <= 3)

        tileid_to_index = np.zeros(T.tileid.max()+1, int)
        tileid_to_index[T.tileid] = np.arange(len(T))
        R.ra  = T.ra [tileid_to_index[R.tileid]]
        R.dec = T.dec[tileid_to_index[R.tileid]]
        
        plt.clf()
        plt.plot(T.ra, T.dec, 'k.', alpha=0.02)
        I = (T.z_done == 1)
        plt.plot(T.ra[I], T.dec[I], 'k.', alpha=0.1)
        plt.plot(R.ra, R.dec, 'b.')
        ax = [310,80,30,85]
        #xl,xh = plt.xlim()
        #plt.xlim(xh,xl)
        plt.xlabel('RA (deg)')
        plt.ylabel('Dec (deg)')
        plt.title('MzLS: retirable pass-%i tiles' % passnum)
        plt.axis(ax)
        ps.savefig()

        for p in [1,2,3]:
            plt.clf()
            plt.plot(T.ra, T.dec, 'k.', alpha=0.02)
            #plt.plot(T.ra[I], T.dec[I], 'k.', alpha=0.1)
            I = np.flatnonzero((T.get('pass') == p) * (T.z_done == 1)
                               * (T.z_depth > 1) * (T.z_depth < 30))
            plt.scatter(T.ra[I], T.dec[I], c=T.z_depth[I],
                        vmin=20, vmax=23, s=4)
            I = np.flatnonzero((T.get('pass') == p) * (T.z_done == 1)
                               * (T.z_depth == 30))
            plt.plot(T.ra[I], T.dec[I], 'k.', alpha=0.5)
            plt.colorbar()
            plt.title('MzLS: Finished tiles in pass %i' % p)
            plt.axis(ax)
            ps.savefig()
            
        sys.exit(0)
    
    # NERSC: export LEGACY_SURVEY_DIR=/global/cscratch1/sd/dstn/dr4plus
    # (dstn laptop: export LEGACY_SURVEY_DIR=~/legacypipe-dir-mzls/)

    survey = LegacySurveyData()
    ccds = survey.get_annotated_ccds()
    print('Annotated CCDs:', len(ccds))
    ccds.cut(ccds.camera == 'mosaic')
    print(len(ccds), 'Mosaic')
    print('Unique exposures:', len(np.unique(ccds.expnum)))

    ccds.cut(ccds.exptime > 60)
    print('Exptime > 60 sec:', len(ccds))
    
    nccds = Counter(ccds.expnum)
    for k,v in nccds.most_common():
        if v <= 4:
            break
        print('Expnum', k, 'appears', v, 'times')
    print('Tile pass numbers:', Counter(ccds.tilepass).most_common())

    # Fix parsing of OBJECT field to tileid...
    from obsbot import get_tile_id_from_name
    tileids = []
    for o in ccds.object:
        tid = get_tile_id_from_name(o.strip())
        if tid is None:
            tid = 0
        tileids.append(tid)
    tileids = np.array(tileids)
    print(len(np.unique(tileids)), 'unique tile ids in annotated file, from OBJECT')
    print(len(np.unique(ccds.tileid)), 'unique tile ids in ann file from TILEID')
    D = np.flatnonzero(tileids != ccds.tileid)
    print(len(D), 'different tileids')
    print('From OBJECT:', tileids[D])
    print('From TILEID:', ccds.tileid[D])
    ccds.tileid = tileids

    T = fits_table('obstatus/mosaic-tiles_obstatus.fits')

    f = open('obstatus/bad_expid.txt')
    bad_expids = []
    for line in f:
        line = line.strip()
        if len(line) == 0:
            continue
        if line[0] == '#':
            continue
        words = line.split()
        try:
            expnum = int(words[0])
        except:
            print('Skipping line:', line)
            continue
        bad_expids.append(expnum)
    print('Read', len(bad_expids), 'bad exposure numbers')

    # Update ccds.tilepass from ccds.tileid
    tileidtopass = dict(zip(T.tileid, T.get('pass')))
    tileidtoebv = dict(zip(T.tileid, T.ebv_med))
    ccds.tilepass = np.array([tileidtopass.get(tileid, 0)
                              for tileid in ccds.tileid])
    ccds.tileebv = np.array([tileidtoebv.get(tileid, 0)
                             for tileid in ccds.tileid])
    print('Tile pass numbers after update:', Counter(ccds.tilepass).most_common())
    e,I = np.unique(ccds.expnum, return_index=True)
    exps = ccds[I]
    #print('Object names,exptimes for tilepass==0:', zip(exps.object[exps.tilepass == 0], exps.exptime[exps.tilepass == 0]))

    # Average the depth per exposure
    for j,expnum in enumerate(exps.expnum):
        I = np.flatnonzero(ccds.expnum == expnum)
        if len(I) != 4:
            print('Exposure', expnum, 'has', len(I), 'CCD entries')
            continue
        # Don't include zeros in computing average depths!
        Igood = I[(ccds.galdepth[I] > 0) * (ccds.ccdzpt[I] < 30)]
        if len(Igood) > 0:
            exps.galdepth[j] = np.mean(ccds.galdepth[Igood])
        else:
            exps.galdepth[j] = 0.

    # CCDs-table-based mapping from tileid to depth.
    I = np.flatnonzero((exps.tilepass > 0) * (exps.galdepth > 0) *
                       (exps.tileid > 0))
    tileid_to_depth = dict(zip(exps.tileid[I], exps.galdepth[I]))

    
    T.cut(T.in_desi == 1)
    T.cut(T.get('pass') <= 3)
    
    # The tiles we'll examine
    P3 = T[T.get('pass') == passnum]
    print(len(P3), 'pass', passnum, 'and in DESI')
    todo = P3[P3.z_done == 0]
    print(len(todo), 'pass', passnum, 'tiles to do (Z_DONE=0)')

    # Tiles with measured depths
    T.cut((T.z_depth > 15) * (T.z_depth < 30))
    print(len(T), 'tiles with measured depths')
    # Passes other than 3... they ~ only barely overlap, so don't
    # contribute significant depth.
    #T.cut(T.get('pass') < 3)

    udecs = np.unique(P3.dec)
    print(len(udecs), 'unique Dec values in pass', passnum)

    # Grab an arbitrary weight-map image and use that as a proxy!
    wtfn = 'k4m_170501_112501_oow_zd_v1.fits.fz'
    F = fitsio.FITS(wtfn)
    tilewcs = []

    # Read the WCS headers for each chip.
    # They make the CRVAL be the boresight for all 4 chips... perfect!
    # (because this means we can just set CRVAL = RA,Dec to shift the WCSes)
    for i in range(1, len(F)):
        hdr = F[i].read_header()
        wcs = wcs_pv2sip_hdr(hdr)
        tilewcs.append(wcs)

    mp = multiproc(threads)

    #args = [(i,t,udecs,P3,T,tilewcs,exps,bad_expids,tileid_to_depth)
    args = [(i,t)
            for i,t in enumerate(todo)]
    thedepths = mp.map(one_tile, args)

    alldepths = []
    retirable = []
    for arg,depths in zip(args, thedepths):
        if depths is None:
            continue
        itile,tile = arg[:2]
        target = 22.5
        req_pcts = [0, 2, 2, 5, 5, 10, 10, 100]
        req_depths = [0, 0, target-0.6, target-0.6,
                      target-0.3, target-0.3, target, target]

        print('  Depths at 2, 5, and 10th percentile vs target:',
              '%.2f' % (depths[2]  - (target - 0.6)),
              '%.2f' % (depths[5]  - (target - 0.3)),
              '%.2f' % (depths[10] -  target))

        alldepths.append((tile.tileid, depths))
        
        if not ((depths[2]  > target - 0.6) and
                (depths[5]  > target - 0.3) and
                (depths[10] > target)):
            continue

        retirable.append((tile.tileid, depths))

        #if len(retirable) == 10:
        #    break
        # if ps.ploti >= 100:
        #     continue
        # 
        # maglo, maghi = 21,23
        # 
        # plt.clf()
        # #plt.subplot(1,2,1)
        # plt.subplot2grid((2,2), (0,0))
        # plt.imshow(depth, interpolation='nearest', origin='lower',
        #            vmin=maglo, vmax=maghi)
        # plt.colorbar(ticks=[np.arange(maglo, maghi+0.01, 0.5)])
        # plt.xticks([]); plt.yticks([])
        # #plt.subplot(1,2,2)
        # plt.subplot2grid((2,2), (1,0))
        # plt.imshow(nexp, interpolation='nearest', origin='lower',
        #            vmin=0, vmax=4)
        # plt.colorbar(ticks=[0,1,2,3,4])
        # plt.xticks([]); plt.yticks([])
        # 
        # ax = plt.subplot2grid((2,2), (0,1), rowspan=2)
        # plt.plot(req_pcts, np.clip(req_depths, maglo, maghi), 'k-',
        #          lw=2, alpha=0.5)
        # plt.plot(pcts, np.clip(depths, maglo, maghi), 'b-')
        # ax.yaxis.tick_right()
        # plt.ylim(maglo, maghi)
        # plt.xlim(0, 100)
        # plt.xlabel('Coverage fraction')
        # plt.ylabel('Existing depth')
        # plt.suptitle('Tile %i' % tile.tileid)
        # ps.savefig()

        #if ps.ploti == 100:
        #    break
        
    # print('Tiles that could be retired:')
    # print('# Tileid 0th-percentile-extcorr-depth 1st-pctile 2nd-pctile ...')
    # for tileid, depths in retirable:
    #     print(tileid, ' '.join(['%.3f' % d for d in depths]))

    R = fits_table()
    R.tileid = np.array ([t for t,d in alldepths])
    R.depths = np.vstack([d for t,d in alldepths])
    R.writeto(depthsfn)

    if len(retirable):
        R = fits_table()
        R.tileid = np.array([t for t,d in retirable])
        R.depths = np.vstack([d for t,d in retirable])
        R.writeto(retirablefn)
    else:
        print('No tiles in pass', passnum, 'are retirable')