コード例 #1
0
def main():
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument('--mzls',
                        action='store_true',
                        help='Set MzLS (default: DECaLS)')
    parser.add_argument('--ann', help='Set annotated-CCDs file')
    opt = parser.parse_args()

    if opt.mzls:
        from mosaic import MosaicNominalCalibration
        from camera_mosaic import database_filename, camera_name
        nom = MosaicNominalCalibration()

        obstatus_fn = 'obstatus/mosaic-tiles_obstatus.fits'
        out_fn = 'mosaic-obstatus-depth.fits'

        bands = 'z'

        declo, dechi = -5, 90

        bad_expid_fn = 'obstatus/bad_expid.txt'

    else:
        from decam import DecamNominalCalibration
        from camera_decam import database_filename, camera_name
        nom = DecamNominalCalibration()

        # ln -s ~/observing/obstatus/bad_expid.txt obstatus/decam-bad_expid.txt

        obstatus_fn = 'obstatus/decam-tiles_obstatus.fits'
        out_fn = 'decam-obstatus-depth.fits'

        bad_expid_fn = 'obstatus/decam-bad_expid.txt'

        bands = 'grz'

        declo, dechi = -20, 35

    f = open(bad_expid_fn)
    bad_expids = set()
    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.add(expnum)
    print('Read', len(bad_expids), 'bad exposure numbers')

    # Convert copilot db to fits.
    import obsdb
    from copilot import db_to_fits
    obsdb.django_setup(database_filename=database_filename)
    ccds = obsdb.MeasuredCCD.objects.all()
    copilot = db_to_fits(ccds)
    all_copilot = copilot.copy()
    fn = 'copilot.fits'
    copilot.writeto(fn)
    print('Wrote', fn)

    print(len(copilot), 'measured CCDs in copilot database')
    copilot.cut(np.array([c.strip() == camera_name for c in copilot.camera]))
    print(len(copilot), 'copilot CCDs with camera = "%s"' % camera_name)
    copilot.cut(copilot.expnum > 0)
    print(len(copilot), 'measured CCDs in copilot database with EXPNUM')

    print('Copilot expfactor extremes:',
          np.percentile(copilot.expfactor[copilot.expfactor != 0], [1, 99]))

    survey = LegacySurveyData()
    if opt.ann:
        ccds = fits_table(opt.ann)
    else:
        print('Reading annotated CCDs files...')
        ccds = survey.get_annotated_ccds()
    print(len(ccds), 'CCDs')

    # 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

    O = fits_table(obstatus_fn)
    print(len(O), 'tiles')

    if opt.mzls:
        from camera_mosaic import fix_expnums
        # Fix MzLS exposure numbers with wrong leading "3".
        fix_expnums(ccds.expnum)
        # Also fix leading "3" in expnums in OBSTATUS file
        fix_expnums(O.z_expnum)
        # And copilot database
        fix_expnums(copilot.expnum)

        print('Z_EXPNUM range:', O.z_expnum.min(), 'min >0:',
              O.z_expnum[O.z_expnum > 0].min(), O.z_expnum.max())

    print('Pass numbers:', np.unique(O.get('pass')))

    if opt.mzls:
        goodtiles = (O.in_desi * (O.dec > 30) * (O.get('pass') <= 3))
        print(sum(goodtiles), 'tiles of interest')
    else:
        goodtiles = (O.in_desi * (O.get('pass') <= 3))
        print(sum(goodtiles), 'tiles in the footprint')

    #O.cut(goodtiles)
    #print('Cut to', len(O), 'tiles of interest')

    # *after* fixing tileids
    allccds = ccds.copy()

    # Map tile IDs back to index in the obstatus file.
    tileid_to_index = np.empty(max(O.tileid) + 1, int)
    tileid_to_index[:] = -1
    tileid_to_index[O.tileid] = np.arange(len(O))

    assert (len(np.unique(O.tileid)) == len(O))

    I = tileid_to_index[O.tileid]
    assert (np.all(I == np.arange(len(O))))

    # Look at whether exposures from other programs are near our tile centers.
    # Basically nope.
    # plt.clf()
    # e,K = np.unique(ccds.expnum, return_index=True)
    # I,J,d = match_radec(O.ra, O.dec, ccds.ra_bore[K], ccds.dec_bore[K],
    #                     1./60., nearest=True)
    # KK = K[np.flatnonzero(ccds.tileid[K] > 0)]
    # I,J,d2 = match_radec(O.ra, O.dec, ccds.ra_bore[KK], ccds.dec_bore[KK],
    #                      1./60., nearest=True)
    # ha = dict(range=(0., 60.), bins=60, histtype='step')
    # plt.hist(d * 3600., color='b', **ha)
    # plt.hist(d2 * 3600., color='r', **ha)
    # plt.xlabel('Distance from tile to nearest DECam boresight (arcsec)')
    # plt.savefig('dists.png')

    notileids = ccds[ccds.tileid <= 0]
    print(len(notileids), 'CCDs have no tileid')
    I, J, d = match_radec(notileids.ra_bore,
                          notileids.dec_bore,
                          O.ra,
                          O.dec,
                          0.5,
                          nearest=True)

    plt.clf()
    plt.hist(d, bins=50)
    plt.xlabel('Distance to nearest tile center (deg)')
    plt.savefig('tiledist.png')

    plt.clf()
    plt.hist(d * 3600, bins=50, range=(0, 30))
    plt.xlabel('Distance to nearest tile center (arcsec)')
    plt.savefig('tiledist2.png')

    ccds.cut(ccds.tileid > 0)
    print(len(ccds), 'CCDs with tileid')

    expnums, I = np.unique(ccds.expnum, return_index=True)
    print(len(expnums), 'unique exposures (with tileids)')

    ccds.photometric = (ccds.ccd_cuts == 0)

    # Compute the mean depth per exposure
    E = ccds[I]
    for expnum in expnums:
        I = np.flatnonzero(ccds.expnum == expnum)
        j = np.flatnonzero(E.expnum == expnum)
        assert (len(j) == 1)
        j = j[0]
        E.photometric[j] = np.all(ccds.photometric[I])
        #E.photometric[j] = np.all(ccds.ccd_cuts[I] == 0)
        if len(np.unique(ccds.photometric[I])) == 2:
            print('Exposure', expnum,
                  'has photometric and non-photometric CCDs')
            non = I[ccds.photometric[I] == False]
            phot = I[ccds.photometric[I]]

            if opt.mzls and len(phot) == 3:
                print('Accepting an exposure with 3 good CCDs')
                E.photometric[j] = True
                # And remove this exposure from the bad_expid list.
                if expnum in bad_expids:
                    bad_expids.remove(expnum)
                    print('Removing exposure', expnum, 'from bad_expid file')

                continue

            for ii in non:
                print(
                    '    http://legacysurvey.org/viewer-dev/?ra=%.3f&dec=%.3f&zoom=11&ccds3&bad=%i-%s'
                    % (ccds.ra_center[ii], ccds.dec_center[ii], expnum,
                       ccds.ccdname[ii]))
                print(
                    '    http://legacysurvey.org/viewer-dev/ccd/decals-dr5/decam-%s-%s-%s/'
                    % (ccds.expnum[ii], ccds.ccdname[ii], ccds.filter[ii]))
            print('  image:', ccds.image_filename[I][0])
            print('  boresight:', ccds.ra_bore[I][0], ccds.dec_bore[I][0])
            #print('  ccdnames:', ccds.ccdname[I])
            print('  photometric:', len(phot), ', non-photometric:', len(non))
            print('  median phot depth:', np.median(ccds.galdepth[phot]))
            #print('  depth:', ccds.galdepth[I])
            print('  non-photometric CCDs:', ccds.ccdname[non])
            print('    depths:', ccds.galdepth[non])
            print('    ccdnmatch', ccds.ccdnmatch[non], 'vs',
                  ccds.ccdnmatch[phot])
            print('    ccdtransp:', ccds.ccdtransp[non], 'vs',
                  ccds.ccdtransp[phot])
            print('    ccd zpt vs frame zpt:',
                  ccds.ccdzpt[non] - ccds.zpt[non])
            dp = ccds.ccdzpt[phot] - ccds.zpt[phot]
            print('      phot ccds zpt vs frame: range', dp.min(), dp.max(),
                  'mean', dp.mean())

            whitelist = [
                346662,
                346664,
                346665,  # S3/S29 striping
                346754,  # one bad chip, wispy
                346967,
                347304,  # M5 globular
                347664,  # zpt scatter
                347744,  # weird eye-shaped ghost; but lots of cov.
                347755,
                347768,
                347769,
                347782,  # shallow, zpt scatter -- wispy pattern on focal plane
                347918,
                347920,  # straddling transparency cut
                347934,
                347936,
                347941,
                347945,
                347947,  # zpt scatter
                392377,
                392380,
                393173,  # bright star
                393671,  # bright star
                393672,
                393673,  # scatter
                425339,
                425340,  # strangely low ccdnmatch
                426225,
                430808,  # globular cluster
                431640,  # bright star
                431644,  # globular
                432154,  # one amp high bias
                432159,  # transp. on boundary
                432179,  # one amp high bias, +
                432747,
                432748,
                432751,  # scatter
                433305,
                433306,  # bright star
                497062,
                497064,
                497065,  # low ccdnmatch
                509516,
                509517,  # bright star
                511247,
                511263,  # low ccdnmatch
                511513,
                511514,  # bright star
                512303,  # bright star
                520560,  # bright star
                521782,  # scatter
                522212,  # bright star
                535138,  # bright stars, satellite hits?
                535141,
                535142,
                535143,
                535149,  # low ccdnmatch
                535210,  # bright star
                535695,  # globular
                536065,  # globular
                536385,  # strangely zero ccdnmatch
                547761,  # nice galaxy
                548257,  # bright star
                553779,  # scatter 
                553795,  # shallow
                554284,  # marginal zpt
                563659,  # zpt scatter
                563850,  # mild striping
                563852,  # ??
                583118,  # bright stars?
                592621,  # marginal zpt, scatter
                592859,  # some pattern noise
                605068,  # ??
                625710,  # strangely low ccdnmatch
                631005,  # bright star
                634493,  # globular
                634786,  # strangely low ccdnmatch
                634877,  # globular
                635535,  # bright star, glob
                635962,  # low ccdnmatch
                635973,  # bias level?
                636018,  # bias level?
                637688,  # bright star
            ]
            blacklist = [
                425328,  # 2.7" seeing
                488244,
                488256,
                488260,
                488261,
                488263,
                488268,  # weird striping
                488270,  # weird striping
                496913,
                496917,
                496918,
                496919,
                496920,
                496921,
                496922,  # 3" seeing
                496923,
                496925,
                496926,
                496927,
                496928,
                496930,  # 3" seeing
                509162,
                509163,
                509166,
                509172,
                509176,
                509182,
                509202,  # 3" seeing
                535471,  # 4" seeing!
                535498,  # 3" seeing
                548218,  # double PSF -- telescope moved?
                563835,  # striping
                563842,  # striping
            ]

            if expnum in whitelist:
                print('** Exposure', expnum,
                      'in whitelist -- marking as photometric')
                E.photometric[j] = True

        # Don't include zeros in computing average depths!
        Igood = I[(ccds.galdepth[I] > 0) * (ccds.ccdzpt[I] < 30)]
        if len(Igood) > 0:
            E.galdepth[j] = np.mean(ccds.galdepth[Igood])
        else:
            E.galdepth[j] = 0.
    del expnums

    keep = np.array([not (expnum in bad_expids) for expnum in ccds.expnum])
    ccds.cut(keep)
    print(len(ccds), 'CCDs NOT in the bad_expids file')

    keep = np.array([not (expnum in bad_expids) for expnum in copilot.expnum])
    copilot.cut(keep)
    print(len(copilot), 'copilot exposures NOT in the bad_expids file')

    keep = np.array([not (expnum in bad_expids) for expnum in E.expnum])
    E.cut(keep)
    print(len(E), 'CCD Exposures NOT in the bad_expids file')

    # plt.clf()
    # plt.plot(O.ra, O.dec, 'k.')
    # plt.axis([360,0,-25,35])
    # plt.title('All tiles')
    # plt.savefig('tiles-all.png')
    #
    # print('in_desi:', np.unique(O.in_desi))
    # plt.clf()
    # J = np.flatnonzero(O.in_desi == 1)
    # plt.plot(O.ra[J], O.dec[J], 'k.')
    # plt.axis([360,0,-25,35])
    # plt.title('In DESI')
    # plt.savefig('tiles-desi.png')
    #
    # print('in_des:', np.unique(O.in_des))
    # plt.clf()
    # J = np.flatnonzero(O.in_des == 1)
    # plt.plot(O.ra[J], O.dec[J], 'k.')
    # plt.axis([360,0,-25,35])
    # plt.title('IN DES')
    # plt.savefig('tiles-des.png')

    #print('Number of exposures of each tile:')
    #print(Counter(E.tileid).most_common())
    print()
    print()
    print('Number of exposures of tiles:')
    for band in bands:
        I = np.flatnonzero(E.filter == band)
        c = Counter(E.tileid[I])
        c2 = Counter([v for k, v in c.most_common()])
        print('  ', band, 'band:', c2.most_common())

    # Detection inverse-variance is the quantity that adds when there are
    # multiple exposures.
    #   detsig1 = ccds.sig1 / ccds.galnorm_mean
    #   depth = 5. * detsig1
    #   # that's flux in nanomaggies -- convert to mag
    #   ccds.galdepth = -2.5 * (np.log10(depth) - 9)

    with np.errstate(divide='ignore', over='ignore'):
        # actually 5*detsig1...
        detsig = 10.**((E.galdepth - 22.5) / -2.5)
        E.detiv = 1. / detsig**2
        E.detiv[E.galdepth == 0] = 0.
        print('Smallest detivs:', E.detiv[np.argsort(E.detiv)[:10]])
        print('w/ galdepths:', E.galdepth[np.argsort(E.detiv)[:10]])
        print('Smallest positive detivs:',
              E.detiv[np.argsort(E.detiv + 1e12 * (E.detiv == 0))[:10]])
        print('w/ galdepths:',
              E.galdepth[np.argsort(E.detiv + 1e12 * (E.detiv == 0))[:10]])

    for band in bands:
        print()
        print('------------------')
        print(band, 'band.')

        # "I" indexes into exposures E.
        I = np.flatnonzero(
            (E.filter == band) * E.photometric * np.isfinite(E.detiv))
        print(len(I), 'photometric exposures in', band)

        # "iv" is parallel to O; will be converted to "galdepth".
        iv = np.zeros(len(O), np.float32)
        # "J" indexes into obstatus tiles O.
        J = tileid_to_index[E.tileid[I]]
        assert (np.all((J >= 0) * (J < len(O))))
        assert (np.all(O.tileid[J] == E.tileid[I]))

        #print('tileid range', E.tileid[I].min(), E.tileid[I].max())
        # d = np.array([degrees_between(*a) for a in
        #               zip(E.ra_bore[I], E.dec_bore[I], O.ra[J], O.dec[J])])
        # print('Degrees between tiles & exposures:', d)

        np.add.at(iv, J, E.detiv[I])
        print('galdepth range:', E.galdepth[I].min(), E.galdepth[I].max())
        print('detiv range:', E.detiv[I].min(), E.detiv[I].max())
        #print('index range:', J.min(), J.max())
        nexp = np.zeros(len(O), int)
        np.add.at(nexp, J, 1)
        print('tile exposure counts:', Counter(nexp))

        # convert iv back to galdepth in mags
        with np.errstate(divide='ignore'):
            galdepth = -2.5 * (np.log10(np.sqrt(1. / iv)) - 9)
            galdepth[iv == 0] = 0.

        # Shallowest before extinction correction
        #I = np.argsort(iv + 1e6*(iv == 0))
        I = np.argsort(galdepth + 50. * (galdepth == 0))
        print(
            'Shallowest depth estimates from annotated CCDs file, before extinction:'
        )
        for i in I[:10]:
            print('  ', galdepth[i], 'iv', iv[i], 'tile', O.tileid[i],
                  'expnum',
                  O.get('%s_expnum' % band)[i])
            e = O.get('%s_expnum' % band)[i]
            j = np.flatnonzero(E.expnum == e)
            print('    galdepth', E.galdepth[j])

        fid = nom.fiducial_exptime(band)
        extinction = O.ebv_med * fid.A_co
        #print('Extinction range:', extinction.min(), extinction.max())
        galdepth -= extinction

        galdepth[iv == 0] = 0.

        # Shallowest galdepth > 0
        I = np.argsort(galdepth + 50. * (galdepth == 0))
        print('Shallowest depth estimates from annotated CCDs file:')
        for i in I[:10]:
            print('  ', galdepth[i], 'tile', O.tileid[i], 'expnum',
                  O.get('%s_expnum' % band)[i])

        #print('galdepth deciles:', np.percentile(galdepth, [0,10,20,30,40,50,60,70,80,90,100]))

        # Z_DONE, Z_EXPNUM but no Z_DEPTH
        missing_depth = np.flatnonzero(
            (O.get('%s_expnum' % band) > 0) * (O.get('%s_done' % band) == 1) *
            (galdepth == 0))
        print('Found', len(missing_depth), 'tiles with', band,
              'DONE and EXPNUM but no DEPTH; setting to DEPTH=30')
        print('  eg, EXPNUMs',
              O.get('%s_expnum' % band)[missing_depth[:10]], 'DATE',
              O.get('%s_date' % band)[missing_depth[:10]])
        # Don't actually update 'galdepth[missing_depth]' until after this next check...

        # Flag tiles that have *only* non-photometric exposures with depth = 1.
        I = np.flatnonzero((E.filter == band) * np.logical_not(E.photometric))
        print(len(I), 'exposures are non-photometric in', band, 'band')
        J = tileid_to_index[E.tileid[I]]
        only_nonphot = J[galdepth[J] == 0.]
        print(len(only_nonphot), 'tiles have only non-photometric exposures')
        print('Marking', len(only_nonphot), 'non-photometric tiles in', band,
              'with depth=1')

        orig_galdepth = galdepth.copy()

        galdepth[missing_depth] = 30.
        galdepth[only_nonphot] = 1.

        J = tileid_to_index[E.tileid[I]]
        nonphot = (galdepth[J] == 1.)
        print('Non-photometric galdepths:', E.galdepth[I])
        print('Non-photometric galdepths:', E.galdepth[I[nonphot]])
        plt.clf()
        phot = np.flatnonzero((E.filter == band) * E.photometric)
        plt.hist(E.galdepth[phot],
                 range=(18, 26),
                 bins=50,
                 histtype='step',
                 color='b',
                 label='Photometric')
        plt.hist(E.galdepth[I[nonphot]],
                 range=(18, 26),
                 bins=50,
                 histtype='step',
                 color='r',
                 label='Non-phot')
        plt.legend()
        plt.savefig('nonphot-%s.png' % band)

        # expnum_to_copilot = np.empty(expnums.max()+1, int)
        # expnum_to_copilot[:] = -1
        # expnum_to_copilot[copilot.expnum] = np.arange(len(copilot))
        expnum_to_copilot = dict([(e, i)
                                  for i, e in enumerate(copilot.expnum)])

        if False:
            # Let's check the accuracy of the copilot's depth estimates...
            target_exptime = copilot.expfactor * fid.exptime
            # What fraction of the target exposure time did we take?
            depth_factor = copilot.exptime / target_exptime
            nomdepth = fid.single_exposure_depth
            depth = nomdepth + 2.5 * np.log10(np.sqrt(depth_factor))
            #print('Copilot predicted depths:', depth)
            IC = np.array(
                [expnum_to_copilot.get(e, -1) for e in allccds.expnum])
            K = np.flatnonzero(IC >= 0)
            ext = np.array([
                e['ugrizY'.index(f)]
                for e, f in zip(allccds.decam_extinction, allccds.filter)
            ])
            dd = allccds.galdepth - ext
            print('Making scatterplot...', len(K), 'points')
            plt.clf()
            #plt.plot(dd[K], depth[IC[K]], 'b.', alpha=0.2, mec='none')
            plt.scatter(dd[K],
                        depth[IC[K]],
                        c=np.clip(copilot.expfactor[IC[K]], 0, 2),
                        s=10,
                        alpha=0.2,
                        edgecolors='none')
            plt.colorbar()
            plt.xlabel('Pipeline depth')
            plt.ylabel('Copilot depth proxy')
            plt.plot([20, 25], [20, 25], 'k-', alpha=0.25)
            plt.plot([20, 25], [20 + 0.1, 25 + 0.1], 'k--', alpha=0.25)
            plt.plot([20, 25], [20 - 0.1, 25 - 0.1], 'k--', alpha=0.25)
            plt.axis([20.5, 23, 21, 23.5])
            plt.title(
                'Copilot vs Pipeline depth estimates.  (color = exp.factor)')
            plt.savefig('depth-copilot-%s.png' % band)
            print('Made scatterplot')

        plt.clf()
        ha = dict(bins=60, range=(0, 30), log=True, histtype='step')
        plt.hist(O.get('%s_depth' % band), color='k', label='Before', **ha)
        plt.hist(orig_galdepth, color='b', label='Annotated CCDs', **ha)

        # Do we have measurements for any of these missing tiles in the copilot db?
        for code in [30, 0]:
            Igal = np.flatnonzero(
                (O.get('%s_expnum' % band) > 0) *
                (O.get('%s_done' % band) == 1) * (galdepth == code))
            expnums = O.get('%s_expnum' % band)[Igal]
            print(
                len(expnums),
                'still marked DONE, with EXPNUM, but missing DEPTH, with code =',
                code)

            Ihuh = np.flatnonzero(
                (O.get('%s_done' % band) == 1) * (galdepth == code))
            print(len(Ihuh), 'tiles marked DONE, without EXPNUM, and DEPTH =',
                  code)

            if len(Ihuh):
                print('Tile ids:', O.tileid[Ihuh])
                for t in O.tileid[Ihuh]:
                    I = np.flatnonzero(E.tileid == t)
                    print('  tile', t, ': exposure numbers:', E.expnum[I])
                    print('  with depths', E.galdepth[I])
                    i = tileid_to_index[t]
                    if i >= 0:
                        print('    depth', galdepth[i])
                    else:
                        print('    no depth')

                # Within an arcmin?
                I, J, d = match_radec(O.ra[Ihuh],
                                      O.dec[Ihuh],
                                      all_copilot.rabore,
                                      all_copilot.decbore,
                                      1. / 60.,
                                      nearest=True)
                print('For', len(Ihuh), 'weird tiles,')
                print(len(I), 'matches within an arcmin in the copilot db')
                print('Smallest distances:', d[np.argsort(d)[:10]])

                I, J, d = match_radec(O.ra[Ihuh],
                                      O.dec[Ihuh],
                                      allccds.ra_bore,
                                      allccds.dec_bore,
                                      1. / 60.,
                                      nearest=True)
                print(len(I), 'matches within an arcmin in the CCDs table')
                print('Smallest distances:', d[np.argsort(d)[:10]])

                O[Ihuh].writeto('weird-%s-%i.fits' % (band, code))

            if len(expnums) == 0:
                continue
            IC = np.array([expnum_to_copilot.get(e, -1) for e in expnums])
            K = np.flatnonzero(IC >= 0)
            expnums = expnums[K]
            # these are the indices into O / galdepth
            Igal = Igal[K]
            co = copilot[IC[K]]
            print(len(expnums), 'matched to copilot database')

            target_exptime = co.expfactor * fid.exptime
            # What fraction of the target exposure time did we take?
            depth_factor = co.exptime / target_exptime
            nomdepth = fid.single_exposure_depth
            print('Nominal single-exposure depth:', nomdepth)
            co.depth = nomdepth + 2.5 * np.log10(np.sqrt(depth_factor))
            print('Copilot predicted depths:', co.depth)
            J = np.flatnonzero(np.isfinite(co.depth))
            co = co[J]
            # indices into O
            Igal = Igal[J]
            print(len(Igal), 'good copilot depth estimates')

            pcts = [0, 1, 5, 25, 50, 75, 95, 99, 100]
            print('Copilot depth percentiles:', np.percentile(co.depth, pcts))

            print('Shallowest exposures:')
            I = np.argsort(co.depth)
            for i in I[:10]:
                print('  Expnum', co.expnum[i], 'depth', co.depth[i],
                      'exptime', co.exptime[i])
            co[I].writeto('depths.fits')

            from astrometry.util.starutil_numpy import mjdtodate
            print('Copilot-matched entries:')
            I = np.argsort(co.expnum)
            for i in I:
                print('  EXPNUM', co.expnum[i], 'date',
                      mjdtodate(co.mjd_obs[i]), '  copilot name',
                      co.filename[i])
                # e = co.expnum[i]
                # I = np.flatnonzero(allccds.expnum == e-1)
                # fn1 = None
                # fn2 = None
                # if len(I):
                #     print('    CCDs file contains', len(I), 'entries for expnum', e-1)
                #     print('      filename', allccds.image_filename[I[0]])
                #     fn1 = allccds.image_filename[I[0]]
                # else:
                #     print('    No CCDs file entries for expnum', e-1)
                # I = np.flatnonzero(allccds.expnum == e+1)
                # if len(I):
                #     print('    CCDs file contains', len(I), 'entries for expnum', e+1)
                #     print('      filename', allccds.image_filename[I[0]])
                #     fn2 = allccds.image_filename[I[0]]
                # else:
                #     print('    No CCDs file entries for expnum', e+1)
                #
                # if fn1 is not None and fn2 is not None:
                #     full1 = os.path.join(survey.get_image_dir(), fn1)
                #     #print('Full path 1:', full1)
                #     if os.path.exists(full1):
                #         print('exists')
                #     full2 = os.path.join(survey.get_image_dir(), fn2)
                #     #print('Full path 2:', full2)
                #     if os.path.exists(full2):
                #         print('exists')
                #     if os.path.exists(full1) and os.path.exists(full2):
                #         dir1 = os.path.dirname(full1)
                #         dir2 = os.path.dirname(full2)
                #         if dir1 == dir2:
                #             #print('dir:', dir1)
                #             fns = os.listdir(dir1)
                #             fns.sort()
                #             fns = [fn for fn in fns if ('oki' in fn or 'ooi' in fn)]
                #             base1 = os.path.basename(full1)
                #             base2 = os.path.basename(full2)
                #             i1 = fns.index(base1)
                #             i2 = fns.index(base2)
                #             print('Files found at list elements', i1, i2)
                #             #print(fns[i1:i2+1])
                #             for fn in fns[i1:i2+1]:
                #                 print('EXPNUM', e, 'range', os.path.join(os.path.dirname(fn1), fn))
                #             if i1 + 4 == i2:
                #                 print('EXPNUM', e, 'expected', os.path.join(os.path.dirname(fn1), fns[i1+2]))
                #             if i1 + 2 == i2:
                #                 print('EXPNUM', e, 'expected', os.path.join(os.path.dirname(fn1), fns[i1+1]))

            #print('Before:', galdepth[Igal])
            galdepth[Igal] = co.depth
            #print('After:', galdepth[Igal])

            Igal = np.flatnonzero(
                (O.get('%s_expnum' % band) > 0) *
                (O.get('%s_done' % band) == 1) * (galdepth == code))
            expnums = O.get('%s_expnum' % band)[Igal]
            print(
                len(expnums),
                'still marked DONE, with EXPNUM, but missing DEPTH with code =',
                code, 'after copilot patching')
            print('Exposure numbers:', expnums)
            print('Exposure dates:', O.get('%s_date' % band)[Igal])

            print('Date counter:',
                  Counter(O.get('%s_date' % band)[Igal]).most_common())

        O.set('%s_depth' % band, galdepth)

        plt.hist(O.get('%s_depth' % band), color='r', label='After', **ha)
        plt.savefig('depth-hist-%s.png' % band)

        #print('Depth deciles: [', ', '.join(['%.3f' % f for f in np.percentile(O.get('%s_depth' % band), [0,10,20,30,40,50,60,70,80,90,100])]) + ']')

        rlo, rhi = 0, 360
        dlo, dhi = declo, dechi
        J = np.flatnonzero(
            (O.in_desi == 1) * (O.in_des == 0) * (O.dec > dlo) * (O.dec < dhi))
        print('Median E(B-V) in DECaLS area:', np.median(O.ebv_med[J]))
        print('Median extinction in DECaLS area, %s band:' % band,
              np.median(extinction[J]))

        I2 = np.flatnonzero((O.get('%s_expnum' % band) > 0) *
                            (O.get('%s_depth' % band) == 30) *
                            (O.get('%s_done' % band) == 1) * (O.in_desi == 1))
        print(len(I2), 'with EXPNUM and DONE and IN_DESI, but no DEPTH')
        # Sort by expnum
        I2 = I2[np.argsort(O.get('%s_expnum' % band)[I2])]
        print('Exposure numbers:', sorted(O.get('%s_expnum' % band)[I2]))
        print('Dates:', sorted(O.get('%s_date' % band)[I2]))
        print('Dates:', np.unique(O.get('%s_date' % band)[I2]))

        for i in I2:
            print('  date',
                  O.get('%s_date' % band)[i], 'expnum',
                  O.get('%s_expnum' % band)[i])

        # for i2,o in zip(I2, O[I2]):
        #     print()
        #     e = o.get('%s_expnum' % band)
        #     print('  Expnum', e, 'orig galdepth', orig_galdepth[i2])
        #     date = o.get('%s_date' % band)
        #     print('  Date', date)
        #     print('  Pass', o.get('pass'), 'Tile', o.tileid)
        #     jj = np.flatnonzero(allccds.expnum == e)
        #     print('  In DESI:', o.in_desi, 'In DES:', o.in_des)
        #     print('  ', len(jj), 'matching CCDs')
        #     if len(jj) == 0:
        #         continue
        #     print('  CCDs OBJECT', [ob.strip() for ob in allccds.object[jj]])
        #     print('  CCDs Tileid', allccds.tileid[jj])
        #     print('  CCDs galdepth', allccds.galdepth[jj])
        #     print('  CCDs photometric', allccds.photometric[jj])
        #
        #     ii = np.flatnonzero(E.expnum == e)
        #     print('  ', len(ii), 'Exposures matching')
        #     if len(ii):
        #         ee = E[ii[0]]
        #         print('  exposure tileid', ee.tileid)
        #         print('  index', tileid_to_index[ee.tileid])
        #         print('  vs i2=', i2)
        #         print('  only_nonphot', only_nonphot[i2], 'missing_depth', missing_depth[i2])
        #
        #     kk = np.flatnonzero(allccds.tileid == o.tileid)
        #     kk = np.array(sorted(set(kk) - set(jj)))
        #     print('  ', len(kk), 'other CCDs of this tile')
        # #print('Dates:', O.get('%s_date' % band)[I])

        from astrometry.util.plotutils import antigray
        rr, dd = np.meshgrid(np.linspace(rlo, rhi, 720),
                             np.linspace(dlo, dhi, 360))
        JJ, II, d = match_radec(rr.ravel(),
                                dd.ravel(),
                                O.ra,
                                O.dec,
                                1.5,
                                nearest=True)
        indesi = np.zeros(rr.shape, bool)
        indesi.flat[JJ] = ((O.in_desi[II] == 1) * (O.in_des[II] == 0))

        plt.figure(figsize=(14, 6))
        plt.subplots_adjust(left=0.1, right=0.99)

        for passnum in [1, 2, 3]:
            print('Pass', passnum)
            plt.clf()

            J = np.flatnonzero(
                (O.in_desi == 1) * (O.in_des == 0) * (O.dec > dlo) *
                (O.dec < dhi) * (O.get('pass') == passnum))
            #plt.plot(O.ra[J], O.dec[J], 'k.', alpha=0.5)

            # Plot the gray background showing the in_desi footprint
            plt.imshow(indesi,
                       extent=[rlo, rhi, dlo, dhi],
                       vmin=0,
                       vmax=4,
                       cmap=antigray,
                       aspect='auto',
                       interpolation='nearest',
                       origin='lower')
            depth = O.get('%s_depth' % band)
            #J = np.flatnonzero((O.get('pass') == passnum) * (depth > 0))

            J = np.flatnonzero(
                (O.get('pass') == passnum) * (depth > 1) * (depth < 30))
            # print('Depths:', depth[J])
            pct = np.percentile(depth[J],
                                [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
            #print('Depth deciles:', np.percentile(depth[J], [0,10,20,30,40,50,60,70,80,90,100]))
            print('Depth deciles: [',
                  ', '.join(['%.3f' % f for f in pct]) + ']')

            if len(J) == 0:
                sys.exit(0)

            target = fid.single_exposure_depth
            print('Target depth:', target)

            cmap = cmap_discretize('RdBu', 11)
            dm = 0.275

            plt.scatter(O.ra[J],
                        O.dec[J],
                        c=depth[J] - target,
                        linewidths=0,
                        cmap=cmap,
                        vmin=-dm,
                        vmax=+dm,
                        zorder=-10,
                        s=1)
            plt.colorbar(ticks=np.arange(-0.25, 0.251, 0.05))

            hh, ww = rr.shape
            rgba = np.zeros((hh, ww, 4), np.float32)
            JJ, II, d = match_radec(rr.ravel(),
                                    dd.ravel(),
                                    O.ra[J],
                                    O.dec[J],
                                    1.,
                                    nearest=True)
            Jy, Jx = np.unravel_index(JJ, rr.shape)
            rgba[Jy, Jx, :] = cmap((np.clip(depth[J[II]] - target, -dm, dm) -
                                    (-dm)) / (dm - (-dm)))
            plt.imshow(rgba,
                       extent=[rlo, rhi, dlo, dhi],
                       aspect='auto',
                       interpolation='nearest',
                       origin='lower')

            I = np.flatnonzero((depth == 0) * (O.get('%s_done' % band) == 1) *
                               (O.get('pass') == passnum))
            plt.plot(O.ra[I], O.dec[I], 'g.')

            plt.title('Band %s, Pass %i' % (band, passnum))
            plt.xlabel('RA (deg)')
            plt.ylabel('Dec (deg)')
            plt.axis([rhi, rlo, dlo, dhi])
            plt.savefig('depth-%s-%i.png' % (band, passnum))

        plt.clf()

        print('Fiducial single-exposure-depth:', fid.single_exposure_depth)

        for passnum in [1, 2, 3]:
            depth = O.get('%s_depth' % band)
            J = np.flatnonzero(
                (O.get('pass') == passnum) * (depth > 1) * (depth < 30))
            depth = depth[J]

            print('Pass', passnum)
            print(sum(depth < fid.single_exposure_depth - 0.25), 'of',
                  len(depth), 'tiles are more than 0.25 mag shallow')

            odepth = O.get('%s_depth' % band)
            K = np.flatnonzero(
                (O.get('%s_done' % band) == 0) * (O.get('pass') == passnum) *
                (odepth > 1) * (odepth < 30))
            print(sum(odepth[K] < fid.single_exposure_depth - 0.25), 'of',
                  len(odepth[K]),
                  'DONE=0 tiles are more than 0.25 mag shallow')

            for k in K:
                print('  EXPNUM',
                      O.get('%s_expnum' % band)[k], 'DATE',
                      O.get('%s_date' % band)[k], 'DEPTH',
                      O.get('%s_depth' % band)[k])

            K = np.flatnonzero(
                (O.get('%s_done' % band) == 1) * (O.get('pass') == passnum) *
                (odepth > 1) * (odepth < 30))
            print(sum(odepth[K] < fid.single_exposure_depth - 0.25), 'of',
                  len(odepth[K]),
                  'DONE=1 tiles are more than 0.25 mag shallow')

            K = np.flatnonzero((O.get('%s_done' % band) == 1) *
                               (O.get('pass') == passnum) * (odepth == 1))
            print(len(K), 'DONE=1 tiles have DEPTH=1 (non-photometric)')

            K = np.flatnonzero((O.get('%s_done' % band) == 1) *
                               (O.get('pass') == passnum) * (odepth == 30))
            print(len(K), 'DONE=1 tiles have DEPTH=30 (unknown depth)')

            K = np.flatnonzero((O.get('%s_done' % band) == 1) *
                               (O.get('pass') == passnum) * (odepth == 0))
            print(len(K), 'DONE=1 tiles have DEPTH=0')

            K = np.flatnonzero((O.get('%s_done' % band) == 0) *
                               (O.get('pass') == passnum) * (odepth != 0))
            print(len(K), 'tiles have DONE=0 but DEPTH != 0')

            mlo, mhi = 21, 24
            plt.hist(np.clip(depth, mlo, mhi),
                     bins=100,
                     range=(mlo, mhi),
                     histtype='step',
                     color=' bgr'[passnum],
                     label='Pass %i' % passnum)
        plt.axvline(fid.single_exposure_depth, color='k')
        plt.axvline(fid.single_exposure_depth - 0.25,
                    color='k',
                    linestyle='--')
        plt.xlabel('Depth (mag)')
        plt.legend(loc='upper left')
        plt.title('Depth: %s' % band)
        plt.savefig('depth-%s.png' % band)

        for passnum in [1, 2, 3]:
            depth = O.get('%s_depth' % band)

            roi = ((O.in_desi == 1) * (O.in_des == 0) * (O.dec > dlo) *
                   (O.dec < dhi) * (O.get('pass') == passnum))

            J = np.flatnonzero(roi)

            done = np.flatnonzero(roi * (O.get('%s_done' % band) == 1))

            redo = np.flatnonzero(roi * np.logical_or(
                (depth > 1) * (depth < 30) *
                (depth < fid.single_exposure_depth - 0.25), depth == 1))

            print(
                'Band %s, pass %i: total tiles %i, done %i, redo %i, keep %i' %
                (band, passnum, len(J), len(done), len(redo),
                 len(done) - len(redo)))

            A = np.flatnonzero(roi * (depth > 1) * (depth < 30) *
                               (depth > fid.single_exposure_depth - 0.25))
            B = np.flatnonzero(roi * (depth > 1) * (depth < 30) *
                               (depth <= fid.single_exposure_depth - 0.25))

            C = np.flatnonzero(roi * (depth == 1))

            D = np.flatnonzero(roi * (depth == 30))

            print(
                'Band %s, pass %i: total tiles: %i, A: %i, B: %i, C: %i, D: %i'
                % (band, passnum, len(J), len(A), len(B), len(C), len(D)))

            plt.clf()
            plt.plot(O.ra[J], O.dec[J], 'ko', alpha=0.1)
            plt.plot(O.ra[done], O.dec[done], 'k.')
            plt.plot(O.ra[redo], O.dec[redo], 'r.')
            plt.axis([360, 0, -20, 38])
            plt.title('Tiles to redo: %s band, pass %i: %i of %i' %
                      (band, passnum, len(redo), len(done)))
            plt.savefig('redo-%s-%i.png' % (band, passnum))

            if band == 'z':

                redo = np.flatnonzero(
                    (O.get('pass') == passnum) * np.logical_or(
                        (depth > 1) * (depth < 30) *
                        (depth < fid.single_exposure_depth - 0.5), depth == 1))

                A = np.flatnonzero(roi * (depth > 1) * (depth < 30) *
                                   (depth > fid.single_exposure_depth - 0.5))
                B = np.flatnonzero(roi * (depth > 1) * (depth < 30) *
                                   (depth <= fid.single_exposure_depth - 0.5))

                print(
                    'Band %s, pass %i: total tiles: %i, A: %i, B: %i, C: %i, D: %i (shallow = 0.5 mag less than target)'
                    % (band, passnum, len(J), len(A), len(B), len(C), len(D)))

                plt.clf()
                plt.plot(O.ra[J], O.dec[J], 'ko', alpha=0.1)
                plt.plot(O.ra[done], O.dec[done], 'k.')
                plt.plot(O.ra[redo], O.dec[redo], 'r.')
                plt.axis([360, 0, -20, 38])
                plt.title(
                    'Tiles to redo (> 0.5 mag shallow): %s band, pass %i: %i of %i'
                    % (band, passnum, len(redo), len(done)))
                plt.savefig('redo2-%s-%i.png' % (band, passnum))

        print('Passes 1-3 combined:')
        depth = O.get('%s_depth' % band)
        J = np.flatnonzero((depth > 1) * (depth < 30))
        depth = depth[J]
        print(sum(depth < fid.single_exposure_depth - 0.25), 'of', len(depth),
              'tiles are more than 0.25 mag shallow')

        odepth = O.get('%s_depth' % band)
        K = np.flatnonzero(
            (O.get('%s_done' % band) == 0) * (odepth > 1) * (odepth < 30))
        print(sum(odepth[K] < fid.single_exposure_depth - 0.25), 'of',
              len(odepth[K]), 'DONE=0 tiles are more than 0.25 mag shallow')

        for k in K:
            print('  EXPNUM',
                  O.get('%s_expnum' % band)[k], 'DATE',
                  O.get('%s_date' % band)[k], 'DEPTH',
                  O.get('%s_depth' % band)[k])

        K = np.flatnonzero(
            (O.get('%s_done' % band) == 1) * (odepth > 1) * (odepth < 30))
        print(sum(odepth[K] < fid.single_exposure_depth - 0.25), 'of',
              len(odepth[K]), 'DONE=1 tiles are more than 0.25 mag shallow')

        K = np.flatnonzero((O.get('%s_done' % band) == 1) * (odepth > 1) *
                           (odepth < 30) * goodtiles)
        print(sum(odepth[K] < fid.single_exposure_depth - 0.25), 'of',
              len(odepth[K]),
              'interesting DONE=1 tiles are more than 0.25 mag shallow')

        K = np.flatnonzero((O.get('%s_done' % band) == 1) * (odepth == 1))
        print(len(K), 'DONE=1 tiles have DEPTH=1 (non-photometric)')

        K = np.flatnonzero(
            (O.get('%s_done' % band) == 1) * (odepth == 1) * goodtiles)
        print(len(K),
              'interesting DONE=1 tiles have DEPTH=1 (non-photometric)')

        K = np.flatnonzero((O.get('%s_done' % band) == 1) * (odepth == 30))
        print(len(K), 'DONE=1 tiles have DEPTH=30 (unknown depth)')

        K = np.flatnonzero(
            (O.get('%s_done' % band) == 1) * (odepth == 30) * goodtiles)
        print(len(K), 'interesting DONE=1 tiles have DEPTH=30 (unknown depth)')

        K = np.flatnonzero((O.get('%s_done' % band) == 1) * (odepth == 0))
        print(len(K), 'DONE=1 tiles have DEPTH=0')

        K = np.flatnonzero(
            (O.get('%s_done' % band) == 1) * (odepth == 0) * goodtiles)
        print(len(K), 'interesting DONE=1 tiles have DEPTH=0')

        K = np.flatnonzero((O.get('%s_done' % band) == 0) * (odepth != 0))
        print(len(K), 'tiles have DONE=0 but DEPTH != 0')

    O.writeto(out_fn)
コード例 #2
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')
コード例 #3
0
I first ran this code for each brick:
legacyanalysis/depth-cut.py
--> generates depthcut/*/ccds-*.fits tables of CCDs that pass the depth cut for that brick

legacyanalysis/check-depth-cut.py
--> to read the per-brick ccds-* tables and cut to the union of all CCDs that pass depth cut in some brick -> depth-cut-kept-ccds.fits

legacyanalysis/dr5-cut-ccds.py
--> to read depth-cut-kept-ccds.fits and cut the (already-created) annotated-ccds table and create the .kd.fits version of the CCDs table

'''

survey = LegacySurveyData()

# Read *old* annotated-CCDs tables.
ann = survey.get_annotated_ccds()
print('Got', len(ann), 'annotated CCDs')
ann.about()

# build mapping from expnum,ccdname to index in ann table.
annmap = dict([((e, c.strip()), i)
               for i, (e, c) in enumerate(zip(ann.expnum, ann.ccdname))])

# Read the *new* zeropoints file.
ccds = fits_table(
    '/global/cscratch1/sd/kaylanb/dr5_zpts/survey-ccds-legacypipe-hdufix-45455-nocuts.fits.gz'
)
print('Read', len(ccds), 'CCDs')

print('Cameras:', np.unique(ccds.camera))
コード例 #4
0
def setup():
    survey = LegacySurveyData()
    ccds = survey.get_annotated_ccds()
    return ccds